2013-02-05 17 views

回答

7

是的。實際上,讀取(內建類型)的任何值都是安全的。

數據競賽只有在某個值與使用它的其他線程同時修改時纔會發生。從標準,關鍵的語句是:

一個數據爭在§1.10/ 21定義:

程序的執行包含一個數據的比賽,如果它包含兩個矛盾的 行動不同的線程,其中至少有一個不是原子的,並且兩個線程都不會發生在另一個線程之前。

其中衝突的在§1.10/ 4定義:

兩個表達評價衝突如果它們中的一個修改存儲器 位置(1.7),而另一個存取或修改相同的存儲器 位置。

因此,您必須在這些讀取和任何寫入之間使用合適的同步。

1

如果變量在其中一個線程中被修改,它通常不是線程安全的。

1

通過線程安全我想你的意思是問他們是否有原子寫入。在C++ 03中,這不是真的,因爲C++ 03並不真正瞭解線程。在C++ 11中,你有std::atomic,這是專門爲指針。

+0

他明確表示他對_reads_感興趣。 –

+0

不是原子寫入。如果我在棧上有一個指針,並且有兩個線程獲得了該指針的地址,並且只是想反覆讀取它的值,是否會導致任何問題? – paul13243546

+0

@ paul13243546:即使只是初始化和刪除,也總是會寫入值。現代CPU對不同的內核使用不同的緩存;結果,在一個核心或另一個核心中可能不會注意到對值的更改。如果要從多個線程訪問它,請使用std :: atomic <>。 –

3

它總是安全的從多個線程讀取值。只有當你寫信給你需要管理併發訪問的數據時。

對於只讀數據唯一可能的問題是確保該值實際上在讀取完成時已初始化。如果你在開始你的線程之前初始化這個值,你會沒事的。

+1

從多個線程讀取值並不總是安全的。許多CPU對每個內核使用單獨的緩存,因此在一個內核上更改值可能不會在另一個內核中顯示。 'volatile'不能解決這個問題,因此你必須使用顯式加載和存儲(由std :: atomic <>提供奇妙的)。儘管有問題的參數,即使只是初始化和刪除,也總會有*寫入值。 –

+2

@ Soupd'Campbells - 再次說明:如果您所做的所有**都是閱讀,您**不需要同步,除非確保已初始化該值。在你開始任何線程之前進行初始化處理。 –

+0

這個推論應該是你答案中的第一個*事項,以免有人撇棄(像我一樣)錯誤地說你在說什麼。爲此我建議編輯。 –