2017-04-24 71 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(); 
} 
相关问题