4

プログラムの終了時に適切にクリーンアップしようとしているので、終了するのを待つように呼び出しjoin()ています。std::threadこれは単にメインスレッドを永遠にブロックしているように見えますが、ワーカースレッドは次のような (ほぼ) 空のループであるため、その理由はわかりません。

void GameLoop::Run()
{
    while (run)
    {
        //  Do stuff... 
    }   
    std::cout << "Ending thread...\n";
}

もちろん、ing のrun前に false に設定しています。join今、私はそれがメンバー関数であり、オブジェクトの破壊時に呼び出されることに関係があるのではないかと疑っています。私は次のようなスレッドを作成していrunThread.reset(new thread(&GameLoop::Run, this));ますrunThread: 呼び出しは、オブジェクトのデストラクタで行われます。unique_ptr<std::thread>GameLoopjoin()GameLoop

オブジェクトが破棄される過程にある場合、ループ スレッドが終了できないのではないでしょうか? デバッガーによると、ループ スレッドは の暗い深さに残りますmsvcr120d.dll。もしそうなら、あなたはそれをどのように扱いますか?

注意:std::threadここは初めてです!

更新:これは、デストラクタに参加するための私の呼び出しです:

run = false;
if (runThread->joinable())
{
    runThread->join();
}

更新 2:を削除すると、 !join()によって例外が発生します。~thread()

4

2 に答える 2

5

もちろん、joinスレッドを終了させないスレッドの場合。そのスレッドが自然な (または不自然な) 原因で死ぬまで、単純にブロックします。

マルチスレッド アプリケーションを正常にクリーンアップするには、何らかの方法でワーカー スレッドに終了する時間であることを伝え、終了するのを待つ必要があります。「死が起こるのを待つ」部分がjoin目的です。

于 2013-11-13T18:58:10.150 に答える
1

どうやらランタイム ライブラリにバグがあるようです。この質問によると、スレッドは静的オブジェクトのデストラクタで正常に終了しません。MyGameLoopは static に含まれる非静的オブジェクトGameSystemです。これが本当かどうかを確認して更新します。

はい、確認しました。最初の使用でバグに遭遇したのは運が良かっただけです!

于 2013-11-13T19:50:10.490 に答える