![](/img/trans.png)
[英]Is joinable() then join() thread-safe in std::thread?
[英]What is the reason for a joinable std::thread not join automatically?
有时,如果可连接的std::thread
能够在其析构函数上执行thread::join()
会很有用。 请参阅下面的示例。
示例 1(错误):抛出异常后对象std::thread
已被销毁。 一旦流退出作用域,析构函数就会在连接发生之前被调用。 它使 STL 显示“中止”错误消息。
int main( int argc, const char * argv[] )
{
try
{
thread t( [] ()
{
this_thread::sleep_for( chrono::seconds( 1 ) );
cout << "thread done" << endl;
} );
throw exception( "some exception" );
t.join();
}
catch ( const exception & )
{
cout << "exception caught!" << endl;
}
cout << "main done" << endl;
return 0;
}
示例 2(正确方法):对象t
在我的 try-catch 块之前创建,并且 join() 放在 try 和 catch 块上。 所以它保证了 join() 发生。
int main( int argc, const char * argv[] )
{
thread t;
try
{
t = thread( [] ()
{
this_thread::sleep_for( chrono::seconds( 1 ) );
cout << "thread done" << endl;
} );
throw exception( "some exception" );
t.join( );
}
catch ( const exception & )
{
t.join();
cout << "exception caught!" << endl;
}
cout << "main done" << endl;
return 0;
}
...而问题是:可连接的std::thread
不能在其析构函数上自动连接的原因是什么?
如果它自动发生会容易得多。 例如,今天的做法要求人们在 try-catch 块内使用线程时必须小心……但我相信有人在以这种方式设计std::thread
认为。 所以一定是有原因的……那是什么原因?
PS:我知道我们可以在一个类中包含std::thread
并将join()
放在这个新类的析构函数上......所以它变得自动了。 但这不是重点。 我的问题实际上是关于std::thread
本身的。
原因很简单,让你不得不去思考。 如果std::thread
对象由于超出范围的异常而被销毁,则连接可能会在堆栈展开期间导致阻塞等待,这通常是不可取的,并且如果正在等待的线程依次等待,则可能导致死锁对于执行等待的线程部分的某些操作。
通过在这种情况下终止应用程序,您作为程序员被迫积极考虑会导致对象被销毁的条件,并确保线程正确连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.