可以從m_flag
的定義這裏刪除volatile
安全嗎? 如果m_flag
不是易失性的,什麼會阻止編譯器優化掉這個循環的條件:while (!m_flag) m_cv.wait(lock);
? 標準(post-C++ 11)明確指出在這種情況下禁止這種優化嗎?在這裏刪除C++ volatile是否安全?
#include <mutex>
#include <condition_variable>
#include <future>
#include <iostream>
using namespace std;
class foofoo
{
volatile bool m_flag;
mutex m_mutex;
condition_variable m_cv;
public:
void DoWork()
{
m_flag = false;
unique_lock<mutex> lock(m_mutex);
auto junk = async(std::launch::async, [this]()
{
{
unique_lock<mutex> lock(m_mutex);
m_flag = true;
}
m_cv.notify_one();
});
while (!m_flag) m_cv.wait(lock);
cout << "ququ" << endl;
}
};
int main()
{
foofoo f;
f.DoWork();
}
謝謝!換句話說,如果循環的主體不改變循環條件,但包含同步「點」,爲了優化它,編譯器將不得不分析循環條件是否可能受到「可見側效果「從另一個可以同步」點「的線程?在實踐中,編譯器可能會放棄,永遠不會試圖優化這種循環? –
我的意思是「優化循環的條件」。我剛剛意識到我到處都在說「循環」,但很顯然循環將保持,只是變成一個無限循環... –
@MaxGalkin只要你不寫數據競爭,編譯器必須確保更改由先前釋放互斥體的線程創建的線程對隨後獲取相同互斥體的線程可見。我不確定我是否會說「永遠不要嘗試」,但只要代碼沒有數據競爭,就不會有符合編譯器的意外。 –