2012-05-20 54 views
1

如果我不在乎是否Thread1更改Flag1在同一時間Thread2更改Flag1,除了邏輯錯誤還有什麼可擔心的嗎?這將導致系統崩潰等,如果:同時讀取/寫入線程

  1. Thread1Thread2在準確的同時讀取Flag1
  2. Thread1正在寫Flag1Thread2正在讀Flag1

在這些例子中,Flag1bool

+1

您可能需要仔細考慮「完全相同的時間」的真正含義以及數字設備上的這些操作是如何發生的。 – dmckee

+1

除非該標誌是一個objecttyat的屬性,否則它本身不會發生崩潰。但是你可能會錯過狀態變化,或者在兩個線程中檢測到相同的變化。所以會發生什麼取決於國家的變化。因爲你不關心程序邏輯,所以爲什麼你甚至不打擾?讓它安全線程比試圖處理它不安全的後果要容易得多「_besides logic errors_」 –

+0

「_besides logic errors_」一個更簡單的程序是「你好世界」。它可能不會做你想做的事情,但是當你不關心邏輯錯誤時...... – curiousguy

回答

7

根據該C++ 11內存模型的規則:

  1. 線程1和線程在準確的同一時間讀取標誌1?這總是安全的。
  2. 線程1在與Thread2讀取標誌1的同一時間寫入Flag1?這是一場數據競賽。

數據競爭是未定義的行爲。雖然它不太可能在任何理智的硬件上崩潰,但它是未定義的行爲,所以任何事情都可能發生。

+0

誰說它是C++ 11? –

+3

C++ 03沒有提到線程,所以不能保證**任何**都可以工作。 C++ 11提供了編譯器和硬件供應商同意的保證,並且大部分代表了現有實踐的形式化。你有更好的來源保證什麼是保證,哪些不是?我不這樣做,所以只能用C++ 11內存模型來回答。 –

+2

@EitanT:問題被標記爲「C++多線程」。在C++ 03中沒有「線程」的概念,所以推理必須是C++ 11,Jonathan的答案是目前唯一正確的答案。如果提問者想要了解一些特定於平臺的線程模型,他需要確定平臺。 – Nemo

-1

該標誌應該標記爲volatile。這將確保您的編譯器不會以不一致的方式優化讀取/寫入。

我相信讀/寫bool是原子 - 所以我不認爲你會有任何其他問題,如果你不關心訪問的順序。

+1

不,「volatile」與線程無關,並且不,對bool的訪問不保證是原子性的(某些硬件可能會提供更強的保證,但這不是可移植的。)雖然volatile會阻止編譯器重新排序讀取和寫入,但它不會阻止硬件重新排序。使用原子類型或原子操作來獲取正確的語義。 –

+0

@JonathanWakely嗯..我很抱歉我不明白 - 你爲什麼說揮發性與線程無關? – Chip

+0

@JonathanWakely - 他不在乎重新訂購 – Chip

2

據我所知,2個線程不能在完全相同的時間訪問相同的內存。

即使在並行計算中,這些假設也會由處理器自動處理。 http://en.wikipedia.org/wiki/Parallel_Random_Access_Machine

所以答案是沒有崩潰。 你當然會有邏輯錯誤,但是因爲你不在意:p。

+0

「_2線程不能同時訪問相同的內存。」_共享內存怎麼樣? –

+0

同一時間在時鐘的意義。他們實際上輪流訪問內存。 –

+0

我明白你的意思了,但我會說你的措辭有點誤導。 –