中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

volatile關鍵字

發布時間:2020-02-29 00:02:50 來源:網絡 閱讀:189 作者:flag不會倒 欄目:開發技術

首先簡單介紹一下編譯器對代碼優化的概念:
編譯器優化:在不影響程序結果的情況下,改變程序的執行順序提高效率
優化級別有:
O0 O1 O2 O3
優先級別越高,優化的越厲害
如何優化?在此介紹volatile,我們只談優化的一個方式,就是將頻繁使用的變量直接加載到離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){}                                                                                                        
}

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

#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,這時候不管怎么優化flag都是從內存中讀取的,一改變他就可以讀入新的值,因而這個程序當接收到2信號時就可以正常退出了。

volatile要經常使用在多線程中,因為編譯器對于多執行流的情況不太會判斷,所以volatile經常要使用在多線程來讓cpu用的變量都是新的。

與volatile相對的是register,即告訴編譯器把這個變量放到寄存器中。
但是這register個關鍵字不經常用了因為編譯器知道什么變量該放什么不該放,會自動優化。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丹江口市| 邛崃市| 鹤山市| 伊宁市| 延边| 天长市| 阳城县| 革吉县| 驻马店市| 浮梁县| 威宁| 龙泉市| 宜君县| 冀州市| 吉水县| 墨竹工卡县| 青龙| 黔南| 新和县| 宣武区| 奉化市| 南召县| 石台县| 江口县| 柘城县| 宁津县| 松江区| 新乐市| 澄江县| 茌平县| 长子县| 白河县| 宁阳县| 六安市| 札达县| 连城县| 冷水江市| 乡宁县| 荆州市| 包头市| 绥中县|