多線程編程問題

1. int變量操作的原子性

x86彙編中,對任何內存地址中的1byte的讀永遠是原子的。可以總結爲:在對齊的情況下,小於處理器位數的數據讀取是原子的。但在C++中,使用強制轉換後的內容不再保證對齊,於是就沒有了原子性。基於這些原因,在程序中應該直接atomic相關的函數來保證原子性。

2. volatile在多線程中應該怎麼用

上一條中說明了不能用一個變量來保證原子性,即使加上volatile也沒用。在多線程中,volatile應該用於在加鎖的前提下,防止指令不會因編譯器的優化而省略,且要求每次直接讀值。

3. 什麼是指令亂序

處理器亂序 是指在執行指令時,如果後一第指令不依賴前一條的執行結果,則後一條指令有可能會在前一條指令返回前執行。處理器亂序不會對上層的運行結果產生影響。

編譯器亂序 是爲了優化處理器亂序,受到處理器預取單元的能力限制,處理器每次只能分析一小塊指令,編譯器能夠對很大一個範圍的代碼進行分析,並將其儘量靠近排列讓處理器更容易預取和併發執行。

通常簡單地使用volatile關鍵字就可以解決編譯器的亂序問題(並不能保證編譯器不做其他任何優化),但是這些指令到了處理器執行的時候,仍然可能被亂序。對於處理器亂序執行的避免就需要用到一組 內存屏障 函數(barrier)了。

對於切實是需要保障訪存順序的代碼,就算當前使用的編譯器能夠編譯出有序的目標碼來,我們也還是必須通過設置內存屏障的方式來保證有序,否則都是不嚴謹,有隱患的。

4. 自旋鎖

自旋鎖與互斥鎖類似,只是自旋鎖不會引起調用者睡眠,如果自旋鎖已經被別的執行單元保持,調用者就一直循環查詢鎖的保持者是否已經釋放了鎖。因爲自旋鎖不會引起調用者睡眠,所以自旋鎖的效率高於互斥鎖,但也應該考慮其一直佔用CPU帶的影響,適用於鎖持有時間短,不希望在調度上花太多成本。在《APUE》11.6.7有詳細介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章