簡體   English   中英

可連接的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM