web-dev-qa-db-ja.com

いつstd :: thread :: detachを使用すべきですか?

いつかstd::threadを使用してアプリケーションを高速化する必要があります。 join()は、スレッドが完了するまで待機することも知っています。これは簡単に理解できますが、detach()を呼び出すことと呼び出さないことの違いは何ですか?

detach()がなければ、スレッドのメソッドは独立してスレッドを使用して機能すると思いました。

切り離さない:

void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called without detach");
    });

    //some code here
}

切り離して呼び出す:

void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called with detach");
    });

    t.detach();

    //some code here
}
115
Jinbom Heo

std::threadのデストラクタでは、次の場合にstd::terminateが呼び出されます。

  • スレッドは(t.join()で)結合されませんでした
  • どちらも切り離されていません(t.detach()を使用)

したがって、実行フローがデストラクタに到達する前に、常にスレッドをjoinまたはdetachにする必要があります。


プログラムが終了するとき(つまり、mainが戻る)、バックグラウンドで実行されている残りの切り離されたスレッドは待機されません。代わりに、実行が中断され、スレッドローカルオブジェクトが破壊されます。

重要なことは、これはこれらのスレッドのスタックが巻き戻されないであり、したがって、一部のデストラクタが実行されないことを意味します。これらのデストラクタが引き受けるはずのアクションによっては、これはプログラムがクラッシュしたり、殺されたりしたのと同じくらい悪い状況かもしれません。 OSがファイルなどのロックを解除することを願っていますが、共有メモリ、半分書き込まれたファイルなどが破損している可能性があります。


したがって、joinまたはdetachを使用する必要がありますか?

  • joinを使用
  • より柔軟性が必要であり、スレッドの完了を待つ同期メカニズムを提供する意思がない限り独自に、その場合はdetachを使用できます
121
Matthieu M.

スレッドがdetachで完了するのを待たない場合は、joinを呼び出す必要がありますが、スレッドは完了するまで実行を続け、その後、メインスレッドが特に待機することなく終了します。

detachは、基本的にjoinを実装するために必要なリソースを解放します。

スレッドオブジェクトの寿命が終わり、joindetachも呼び出されなかった場合、致命的なエラーになります。この場合、terminateが呼び出されます。

21
6502

スレッドをデタッチすると、join()を終了する前にmain()する必要がないことを意味します。

スレッドライブラリは実際にそのようなスレッドを待機しますbelow-mainですが、気にする必要はありません。

detach()は主に、バックグラウンドで実行する必要があるタスクがあるが、その実行を気にしない場合に役立ちます。これは通常、一部のライブラリの場合です。気付かないように、バックグラウンドワーカースレッドを静かに作成して切り離すことがあります。

9
GreenScape

cppreference.com によると:

実行のスレッドをスレッドオブジェクトから分離し、実行を独立して続行できるようにします。割り当てられたリソースは、スレッドが終了すると解放されます。

Detachを呼び出した後、*thisはスレッドを所有しなくなりました。

例えば:

  std::thread my_thread([&](){XXXX});
  my_thread.detach();

ローカル変数my_threadに注意してください。my_threadの有効期間が終了すると、std::threadのデストラクタが呼び出され、デストラクタ内でstd::terminate()が呼び出されます。

ただし、detach()を使用する場合は、my_threadのライフタイムが終了しても、my_threadを使用しないでください。新しいスレッドには何も起こりません。

1
DinoStray