2017-11-15 11 views
0

次のコードでは、私はmLooperMutexを子スレッドが取得できないと考えます。しかし、プログラムの出力は非常に驚くべきことです。それは、std :: threadでキャプチャされたmLooperMutexがメインスレッドのものと同じではないようです。std :: mutexはstd :: thread間で共有できません

しかし、std :: threadのdetach()呼び出しをjoin()に変更した場合、mLooperMutexがメインスレッドによってロックされているため、デッドロックが発生します。

異なるスレッド間でmLooperMutexを使用したい場合、このプログラムに問題はありますか?

のa.out: メイン:1が
子を開始通知:メイン行わ1
に通知:
子を行って取得ロック:取得ロック
子供を開始:condは
子供が始まる待つ指揮を待ちます

#include <iostream> 
#include <thread> 
#include <mutex> 
#include <condition_variable> 

using namespace std; 

int main() 
{ 
    std::condition_variable looperSet; 
    bool child_done = false; 
    std::mutex mLooperMutex; 

    cout << "main: acquiring lock begin" << endl; 
    std::unique_lock<std::mutex> lock(mLooperMutex); 
    cout << "main: acquiring lock done" << endl; 

    std::thread{[&mutex=mLooperMutex, &looperSet, &child_done]() { 
     cout << "child: acquiring lock begin" << endl; 
     std::unique_lock<std::mutex> lock(mutex); 
     cout << "child: acquiring lock done" << endl; 
     child_done = true; 
     lock.unlock(); 

     cout << "child: notify one begin" << endl; 
     looperSet.notify_one(); 
     cout << "child: notify one done" << endl; 


    }}.detach(); 

    cout << "main: wait cond begin" << endl; 
    looperSet.wait(lock, [&child_done]{ return child_done; }); 
    cout << "main: wait cond done" << endl; 

    return 0; 
} 

答えて

2

を行って、なぜmLooperMutex理由スレッドは、「できるスレッドの.join()待ち、先に進む前に終了するので、これは.join()では動作しない理由がある

// This unlocks "lock", and then locks it again afterwards. 
looperSet.wait(lock, [&child_done]{ return child_done; }); 

、および:ロックがlooperSet.waitによって解放されるため、子スレッドである取得することができますロックが解除されるまで終了し、ロックを解除するlooperSet.wait().join()が終了するまで実行されません。

スレッドを作成してすぐに.join()を呼び出すことはあまり役に立ちません。スレッドを使用するのではなくコードを直接実行することもできます。

+0

あなたはポイントを得る。ありがとうございました。 – ray

関連する問題