C++のマルチスレッドでのjoin()
とdetach()
の違いは何ですか? join()
はスレッドを強制終了しますか?
C++ thread
オブジェクトは一般に(常にではありませんが)OSまたはプラットフォームの概念である実行のスレッドを表します。
thread::join()
が呼び出されると、呼び出しスレッドは実行スレッドが完了するまでブロックします。基本的に、これはスレッドがいつ終了したかを知るために使用できるメカニズムの1つです。 thread::join()
が戻ると、OSの実行スレッドが完了し、C++ thread
オブジェクトを破棄できます。
thread::detach()
が呼び出され、実行スレッドがthread
オブジェクトから「切り離され」、thread
オブジェクトによって表されなくなります。これらは2つの独立したものです。 C++ thread
オブジェクトを破棄し、OSの実行スレッドを続行できます。プログラムがその実行スレッドがいつ完了したかを知る必要がある場合、他のメカニズムを使用する必要があります。 join()
は、そのthread
オブジェクトで実行できなくなりました。実行のスレッドに関連付けられなくなったためです。
C++ thread
オブジェクトを「結合可能」のまま破棄するとエラーと見なされます。つまり、C++ thread
オブジェクトを破棄するには、join()
を呼び出す(および完了する)か、detach()
を呼び出す必要があります。 C++ thread
オブジェクトが破棄されたときにまだ結合可能な場合、例外がスローされます。
C++ thread
オブジェクトが実行のスレッドを表さない他のいくつかの方法(つまり、結合できないことがあります):
thread
オブジェクトは実行のスレッドを表さないため、結合できません。join()
はスレッドを強制終了しません。実際には、スレッドのメイン関数が戻るまで待機します。したがって、スレッドのメイン関数が次のようになっている場合:
_while (true) {
}
_
join()
は永遠に待機します。
detatch()
もスレッドを殺しません。実際、_std::thread
_オブジェクトが破棄された場合でも、このスレッドは実行を継続する必要があることを_std::thread
_に伝えます。 C++はstd :: threadデストラクターでスレッドが結合または切り離されていることをチェックし、このチェックが失敗するとプログラムを終了します。
したがって、次のコードのmain
関数の最初の行のコメントを解除すると、クラッシュします。 2行目または3行目のコメントを外すと正常に機能します。
_#include <thread>
void func() {
}
void fail1() {
std::thread t(func);
// will fail when we try to destroy t since it is not joined or detached
}
void works1() {
std::thread t(func);
t.join();
}
void works2() {
std::thread t(func);
t.detach();
}
int main() {
// fail1();
// works1();
// works2();
}
_