2016-11-30 56 views
0

考慮下面的代碼:代碼被編譯器跨互斥邊界重新排序

int a = 0, b = 0; 
boost::mutex m; 
a++; 
m.lock(); 
m.unlock(); 
b++; 

做什麼鎖是他們告訴編譯器「好吧,忘記了片刻的C++標準,我不在乎什麼優化如果你嚴格遵循這個規則,它將被允許。你不能重新排序跨越這個邊界的任何內存訪問「。這是否意味着a++;將始終在b++;之前發生?或者這是否意味着,如果在鎖之間有聲明,請不要使用a++b++重新排序?

+5

鑑於編譯器可以看到'a'和'b'是局部變量,它可以像往常一樣優化它們。在給定的代碼中,另一個線程無法看到有問題的「int」,所以互斥體不會影響它們。 –

回答

0

這個問題已經很好地回答了Baum mit Augen的評論。

但是,如果「A」和「B」是全球變量,取決於編譯器互斥鎖徵收的內存屏障可保證讀宣佈揮發性,/寫表達式將不會在重新排序邊界。

這意味着讀取「b」並且發現它的線程已經增加,並且在此之後執行類似的互斥鎖以施加內存屏障,並且最後讀取「a」,保證發現「a」具有也被修改了。

MSVC有這種行爲,還有一些其他編譯器。