[英]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.