2017-04-11 13 views
1

私のアプリケーション用のスレッドプールが必要なので、std::map<int, std::thread>オブジェクトを作成できました。私はこのように単純化することができますいくつかの非常に予期しない動作、遭遇した :std :: threadを使用してstd :: threadを使用すると予期しない動作が発生する

std::map<int, std::thread> threads; 

threads.insert(std::pair<int, std::thread>(1, std::thread([]() { 
     std::cout << "I'm the first thread and I'm gonna work\n"; 
    }))); 
threads[1].join(); 

std::cout << "Thread 1 joinable? " << threads[1].joinable() << "\n"; 

threads.insert(std::pair<int, std::thread>(1, std::thread([]() { 
     std::cout << "I'm not gonna work at all\n"; 
    }))); 
threads[1].join(); 

に出力が

I'm the first thread and I'm gonna work 
Thread 1 joinable? 0 

右後、std::terminate()が呼び出され、プログラムがSIGABRTシグナルを受信して​​います。

ライブデバッグでは、joinable()がtrueであるため、terminateが呼び出されていることが示唆されましたが、私はそれをチェックしていませんでした。

また、それを克服する方法はjoin() INGの後に次の行を追加するだけだった。

threads.erase(1); 

std::threadの新しいインスタンスがちょうど私の前に作成されたように見えるよう、少し混乱私の葉insertコール...誰かがこの予期しない動作について私にヒントを与えることができますか? http://en.cppreference.com/w/cpp/container/map/insertから

+0

stdoutでトレースするときは、フラッシュするのを忘れないでください。 – molbdnilo

+0

@molbdnilo - 改行はそうするべきです。 –

+0

@OliverCharlesworth ''\ n''は' std :: cout'をフラッシュしません。 –

答えて

4

:容器に

インサート要素(複数可)、コンテナは既に等価のキーを持つ要素が含まれていない場合。

マップにはすでに1の要素が含まれているため、2番目のthreads.insertは何もしません。あなたは単に同じに2回参加しようとしていますstd::thread。このため、threads.erase(1);が問題を解決し、マップにはキー1のスレッドが含まれなくなりました。

+0

ありがとうございます。既存のキーをオーバーライドするための簡単なAPIはありません。 –

+0

@OmerPerry 'treads [1] = std :: thread([](){/ * do work * /});'は新しいものでキー '1'のスレッドを上書きします。 1回の呼び出しで要素を削除して削除する方法はありませんが、移動割り当てはすべての移動可能なタイプに対して同じ処理を行う必要があります。 –

関連する問題