いつか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
}
std::thread
のデストラクタでは、次の場合にstd::terminate
が呼び出されます。
t.join()
で)結合されませんでしたt.detach()
を使用)したがって、実行フローがデストラクタに到達する前に、常にスレッドをjoin
またはdetach
にする必要があります。
プログラムが終了するとき(つまり、main
が戻る)、バックグラウンドで実行されている残りの切り離されたスレッドは待機されません。代わりに、実行が中断され、スレッドローカルオブジェクトが破壊されます。
重要なことは、これはこれらのスレッドのスタックが巻き戻されないであり、したがって、一部のデストラクタが実行されないことを意味します。これらのデストラクタが引き受けるはずのアクションによっては、これはプログラムがクラッシュしたり、殺されたりしたのと同じくらい悪い状況かもしれません。 OSがファイルなどのロックを解除することを願っていますが、共有メモリ、半分書き込まれたファイルなどが破損している可能性があります。
したがって、join
またはdetach
を使用する必要がありますか?
join
を使用detach
を使用できますスレッドがdetach
で完了するのを待たない場合は、join
を呼び出す必要がありますが、スレッドは完了するまで実行を続け、その後、メインスレッドが特に待機することなく終了します。
detach
は、基本的にjoin
を実装するために必要なリソースを解放します。
スレッドオブジェクトの寿命が終わり、join
もdetach
も呼び出されなかった場合、致命的なエラーになります。この場合、terminate
が呼び出されます。
スレッドをデタッチすると、join()
を終了する前にmain()
する必要がないことを意味します。
スレッドライブラリは実際にそのようなスレッドを待機しますbelow-mainですが、気にする必要はありません。
detach()
は主に、バックグラウンドで実行する必要があるタスクがあるが、その実行を気にしない場合に役立ちます。これは通常、一部のライブラリの場合です。気付かないように、バックグラウンドワーカースレッドを静かに作成して切り離すことがあります。
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
を使用しないでください。新しいスレッドには何も起こりません。