新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > linux系統編程之基礎必備(六):可重入函數、sig

        linux系統編程之基礎必備(六):可重入函數、sig

        作者: 時間:2016-10-08 來源:網絡 收藏

        是編譯器優化得有錯誤嗎?不是的。設想一下,如果程序只有單一的執行流程,只要當前執行流程沒有改變a的值,a的值就沒有理由會變,不需要反復從內存讀取,因此上面的兩條指令和while(!a);循環是等價的,并且優化之后省去了每次循環讀內存的操作,效率非常高。

        所以不能說編譯器做錯了,只能說編譯器無法識別程序中存在多個執行流程。之所以程序中存在多個執行流程,是因為調用了特定平臺上的特定庫函數,比如sigaction、pthread_create,這些不是C語言本身的規范,不歸編譯器管,程序員應該自己處理這些問題。

        C語言提供了volatile限定符,如果將上述變量定義為volatile sig_atomic_t a=0;那么即使指定了優化選項,編譯器也不會優化掉對變量a內存單元的讀寫。

        對于程序中存在多個執行流程訪問同一全局變量的情況,volatile限定符是必要的,此外,雖然程序只有單一的執行流程,但是變量屬于以下情況之一的,也需要volatile限定:

        變量的內存單元中的數據不需要寫操作就可以自己發生變化,每次讀上來的值都可能不一樣;

        即使多次向變量的內存單元中寫數據,只寫不讀,也并不是在做無用功,而是有特殊意義的;

        什么樣的內存單元會具有這樣的特性呢?肯定不是普通的內存,而是映射到內存地址空間的硬件寄存器,例如串口的

        接收寄存器屬于上述第一種情況,而發送寄存器屬于上述第二種情況。

        sig_atomic_t類型的變量應該總是加上volatile限定符,因為要使用sig_atomic_t類型的理由也正是

        要加volatile限定符的理由。

        對于多線程的程序,訪問沖突的問題是很普遍的,解決的辦法是引入鎖,獲得鎖的線程可以完成“讀-修改-寫”的操作,然后釋放鎖給其它線程,沒有獲得鎖的線程只能等待而不能訪問共享數據,這樣“讀-修改-寫”三步操作組成一個原子操作,要么都執行,要么都不執行,不會執行到中間被打斷,也不會在其它處理器上并行做這個操作。


        上一頁 1 2 下一頁

        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 衡阳县| 茌平县| 龙游县| 云梦县| 黑龙江省| 西乌| 霞浦县| 嵩明县| 江华| 河北省| 泰顺县| 方城县| 衡阳市| 武冈市| 章丘市| 射阳县| 新闻| 库车县| 遵义市| 枝江市| 铅山县| 射阳县| 漾濞| 株洲市| 无锡市| 华安县| 错那县| 松溪县| 宁陕县| 安达市| 渭源县| 仪征市| 桂林市| 佛坪县| 榆社县| 徐州市| 泗洪县| 宝应县| 南安市| 肥西县| 含山县|