2013-02-04 36 views
6

可能重複:
Concurrency: Atomic and volatile in C++11 memory model什麼C++ 11 <atomic>操作/內存命令保證新鮮?

隨着C++ 11 <atomic>說明書中,是有新鮮的任何保證?不同內存訂單的描述只涉及重新訂購(據我所見)。

具體來說,在這種情況下:

#include <atomic> 

std::atomic<int> cancel_work(0); 

// Thread 1 is executing this function 
void thread1_func() { 

    ... 

    while (cancel_work.load(<some memory order>) == 0) { 
     ...do work... 
    } 
} 


// Thread 2 executes this function 
void thread2_func() { 

    ... 

    cancel_work.store(1, <some memory order>); 

    ... 

} 

如果線程1和線程2不共享除了cancel_work任何其他數據,似乎對我來說,不需要任何排序保證和std::memory_order_relax足夠兩個商店和負載。但是,這是否保證線程1將永遠看到cancel_work的更新,而不是隻重複讀取其本地緩存行,而不必從主內存刷新它?如果不是,那麼做出這種擔保的最低要求是什麼?

+1

@UmNyobe之前我沒有找到這個問題的原因是,它似乎是關於揮發物。答案是重複的,但問題在於,不是因爲人們會找到與你提到的「原子和易變」問題不同的東西。 – JanKanis

回答

4

沒有什麼能夠保證:一切都是有序的。即使memory_order_seq_cst只是保證事情發生在一個總的順序。理論上,編譯器/庫/ cpu可以在程序結束時安排來自cancel_store的每個加載。

有一個在29.3p13是

實現一般性發言應在合理的時間量內使原子賣場看到原子的負荷。

但是沒有關於什麼構成「合理的時間量」的規範。

因此:memory_order_relaxed應該很好,但memory_order_seq_cst可能會在某些平臺上更好地工作,因爲緩存行可能會更快地重新加載。

3

看起來this answer也回答我的問題。那麼,希望我的問題能夠幫助Google員工更好地找到它。

線程1「應該」在「合理的時間量」內看到更新的cancel_work,但究竟是什麼合理的(顯然)沒有指定。

2

調用[未由編譯器內聯的函數]將自動重新加載任何寄存器,該寄存器包含非本地的變量。所以只要運行thread1_func()的處理器根據store獲得了緩存內容刷新或更新,它就可以工作。

memory_order_relax應該確保數據(在未來某個時間點)從任何其他處理器緩存刷新[這在x86中是自動的,但不是所有類型的處理器,例如某些ARM處理器需要'代碼驅動的刷新'],但不能保證在其他任何寫入[到正常或原子變量]之前發生。

並注意內存順序隻影響當前線程/處理器。在存儲或加載期間,另一個線程或處理器的功能完全取決於該線程/處理器。我的意思是,在你的情況下,thread1_func()可能能夠在值1已被另一個處理器/線程寫入後的某個小時間內讀取值0。所有的原子操作保證,它都可以獲得舊值或新值,除非你使用memory_order_relax,它不會在線程內的操作之間強制執行加載/存儲的任何次序。然而,無論你使用什麼內存順序,原子應該保證[假設正確的實現]該值最終被更新。在輕鬆的情況下很難分辨出來。