2017-04-24 18 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が戻り、メインが終了するはずです。

条件変数が無期限に待機していることがわかりました。私は間違って何をしていますか?

P.S.私はWin10の午前 - VS2015

+1

あなたが偽の航跡を処理するためのループ内で '' cv.wait(UL、[](){...})をラップする必要はありません++。ライブラリは、述語に対してループを実行します。述語を取らない 'wait()'のオーバーロードを使用した場合、条件変数にC API pthreadsインターフェースを使用している場合と同様に、 'while'ループが必要になります。 –

答えて

2

はデッドロック:main()asyncFunc()cvは、それがロックを主張することはできませんので、それは実行する機会を得ることはありません通知されていてもそうlgのロックを解除することはありません。

てみてください:Cでも

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(); 
} 
関連する問題