溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

volatile關(guān)鍵字

發(fā)布時(shí)間:2020-02-29 00:02:50 來源:網(wǎng)絡(luò) 閱讀:181 作者:flag不會倒 欄目:開發(fā)技術(shù)

首先簡單介紹一下編譯器對代碼優(yōu)化的概念:
編譯器優(yōu)化:在不影響程序結(jié)果的情況下,改變程序的執(zhí)行順序提高效率
優(yōu)化級別有:
O0 O1 O2 O3
優(yōu)先級別越高,優(yōu)化的越厲害
如何優(yōu)化?在此介紹volatile,我們只談優(yōu)化的一個(gè)方式,就是將頻繁使用的變量直接加載到離cpu很近的寄存器中。

我們先來看如下代碼:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int flag=1;
void Handler(int signo){
printf("signo=%d\n",signo);
flag=0;
}
int main(){
signal(2,Handler);
while(flag){}                                                                                                        
}

在不優(yōu)化的情況下直接進(jìn)行編譯,我們可預(yù)見:程序運(yùn)行起來,當(dāng)給這個(gè)進(jìn)程發(fā)送二號信號flag值才會變?yōu)?使循環(huán)結(jié)束程序運(yùn)行結(jié)束。
但當(dāng)用O2使編譯器對這個(gè)代碼進(jìn)行優(yōu)化時(shí),就會發(fā)現(xiàn)按下ctrl+c發(fā)送2號信號時(shí),循環(huán)依舊不會停止。這是為什么呢?
原來:
在編譯器在優(yōu)化過程中,若編譯器判定某個(gè)數(shù)據(jù)是一個(gè)比較高的開銷,然后編譯器沒有檢測到有代碼修改這個(gè)數(shù)據(jù),便會把頻繁使用的數(shù)據(jù)放到了寄存器中(while循環(huán)頻繁使用flag,Handle函數(shù)雖對他進(jìn)行修改但是由內(nèi)核調(diào)用的,編譯器并不知道),編譯器就可能作出了錯(cuò)誤的判斷,這時(shí)就直接把flag這個(gè)值優(yōu)化到寄存器里了,Handle函數(shù)對flag的修改只是改變了內(nèi)存中的flag并沒有改變寄存器中的flag,因而while判斷時(shí)用到寄存器中的flag一直是1.所以循環(huán)就結(jié)束不了。
為了避免這種編譯器的錯(cuò)誤決措,我們引入volatile關(guān)鍵字
這個(gè)關(guān)鍵字修飾變量就是告訴編譯器,這個(gè)變量必須每次都從內(nèi)存中讀,不敢直接加載到寄存器中,即volatile的目的就是保持內(nèi)存可見性

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
volatile int flag=1;
void Handler(int signo){
printf("signo=%d\n",signo);
flag=0;
}
int main(){
signal(2,Handler);
while(flag){}                                                                                                        
}

在flag前加上volatile,這時(shí)候不管怎么優(yōu)化flag都是從內(nèi)存中讀取的,一改變他就可以讀入新的值,因而這個(gè)程序當(dāng)接收到2信號時(shí)就可以正常退出了。

volatile要經(jīng)常使用在多線程中,因?yàn)榫幾g器對于多執(zhí)行流的情況不太會判斷,所以volatile經(jīng)常要使用在多線程來讓cpu用的變量都是新的。

與volatile相對的是register,即告訴編譯器把這個(gè)變量放到寄存器中。
但是這register個(gè)關(guān)鍵字不經(jīng)常用了因?yàn)榫幾g器知道什么變量該放什么不該放,會自動(dòng)優(yōu)化。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI