2012-10-14 29 views
1

這是一個後續Volatile in C++11揮發性在C++ 11 - 跟進

在的問題,有人告訴我,下面的代碼是表現出不確定的行爲在C++ 11,這迷惑了我大忙了。有沒有我可以閱讀的關於C++ 11中volatile的行爲的材料(可能是標準的各個部分)?

或者有人能解釋問題出在哪裏嗎?

#include <iostream> 
#include <chrono> 
#include <thread> 
using namespace std; 

volatile int notify; 

void watcher() 
{ 
    this_thread::sleep_for(chrono::seconds(2)); 
    notify = 1; 
    cout << "Notification sent." << endl; 
} 

int main() 
{ 
    thread(watcher).detach(); 

    notify = 0; 
    while (!notify) 
    { 
     cout << "Waiting." << endl; 
     this_thread::sleep_for(chrono::seconds(1)); 
    } 

    cout << "Notification received." << endl; 

    return 0; 
} 

回答

7

該標準描述了存儲器模型,特別是「數據競賽」(第1.10節)的概念。很明顯,你的代碼有一個變量notify的數據爭用,因此未定義的行爲。

要解決該問題,請通過鎖保護對notify的訪問,或將其設爲原子變量,如std::atomic<int>

+0

真棒我終於設法找到標準的具體部分:_「如果其中一個表達式評估修改內存位置和另一個訪問或 修改相同的內存位置衝突。」_和_「執行程序包含數據競爭,如果它包含兩個不同線程中的衝突動作,其中至少有一個不是原子的,並且兩個都不會發生在另一個線程之前。任何這樣的數據競爭導致 未定義的行爲。「_ –

+0

哇。這是一個非常非常嚴格的規則。 –

+0

嗯,我有點想知道如何編寫一個線程庫,這個規則就位。基本上迫使你依靠編譯器ABI。我猜你必須做的...... –