2017-04-24 112 views
0

考慮下面的代碼片段爲什麼condition_variable無限期地等待

#include <future> 

std::mutex asyncMut_; 
std::atomic<bool> isAsyncOperAllowed = false; 
std::condition_variable cv; 

void asyncFunc() 
{ 
    while (isAsyncOperAllowed) 
    { 
     std::unique_lock<std::mutex> ul(asyncMut_); 
     cv.wait(ul, []() 
     { 
      return isAsyncOperAllowed == false; 
     }); 
    } 
} 

int main() 
{ 
    isAsyncOperAllowed = true; 
    auto fut = std::async(std::launch::async, asyncFunc); 

    std::this_thread::sleep_for(std::chrono::seconds(3)); 

    std::lock_guard<std::mutex> lg(asyncMut_); 
    isAsyncOperAllowed = false; 
    cv.notify_one(); 

    fut.get(); 
} 

我期待,一旦我改變isAsyncOperAllowed變量的狀態,並通知條件變量時,asyncFunc中的條件變量應該退出觀望asyncFync應該返回並且main應該結束。

我在觀察條件變量一直等待無限期。我究竟做錯了什麼?

P.S.我在Win10 - VS2015

+1

此外,在C++中,你不需要包裹'cv.wait(UL,[](){...})'循環內部處理虛假喚醒。該庫爲謂詞執行謂詞循環。如果使用不帶謂詞的wait()重載,則需要使用while循環,就像使用C API pthreads接口獲取條件變量一樣。 –

回答

2

僵局:main()從未解鎖lg所以即使在asyncFunc()cv得到通知,而不會繼續運行,因爲它不能要求鎖的機會。

嘗試:

int main() 
{ 
    isAsyncOperAllowed = true; 
    auto fut = std::async(std::launch::async, asyncFunc); 

    std::this_thread::sleep_for(std::chrono::seconds(3)); 

    { 
     std::lock_guard<std::mutex> lg(asyncMut_); 
     isAsyncOperAllowed = false; 
    } 
    cv.notify_one(); 

    fut.get(); 
} 
相關問題