简体   繁体   English

可连接的 std::thread 不自动连接的原因是什么?

[英]What is the reason for a joinable std::thread not join automatically?

Sometimes it would be useful if a joinable std::thread had the hability to execute thread::join() on its destructor.有时,如果可连接的std::thread能够在其析构函数上执行thread::join()会很有用。 See the examples below.请参阅下面的示例。

Example 1 (error): The object std::thread has been destroyed after the throw of the exception.示例 1(错误):抛出异常后对象std::thread已被销毁。 Once the the flow exits the scope, the destructor is called BEFORE the join happens.一旦流退出作用域,析构函数就会在连接发生之前被调用。 It makes STL show an error message of 'abort'.它使 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;
}

Example 2 (correct way): The object t is created before my try-catch block and the join() is put on both try and catch blocks.示例 2(正确方法):对象t在我的 try-catch 块之前创建,并且 join() 放在 try 和 catch 块上。 So it guarantees that the join() happens.所以它保证了 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;
}

...AND THE QUESTION IS: What is the reason for a joinable std::thread not join automatically on its destructor? ...而问题是:可连接的std::thread不能在其析构函数上自动连接的原因是什么?

It would be much easier if it happened automatically.如果它自动发生会容易得多。 The way it's done today requires one must be careful when using threads inside try-catch blocks, for example... but I am sure someone THOUGHT when designed std::thread this way.例如,今天的做法要求人们在 try-catch 块内使用线程时必须小心……但我相信有人在以这种方式设计std::thread认为。 So there must be a reason for that... what is that reason?所以一定是有原因的……那是什么原因?

PS: I know we can envolve std::thread in a class and put the join() on the destructor of this new class... so it becomes automatic. PS:我知道我们可以在一个类中包含std::thread并将join()放在这个新类的析构函数上......所以它变得自动了。 But this is not the point.但这不是重点。 My question is really about std::thread itself.我的问题实际上是关于std::thread本身的。

The reason is simply so that you are forced to think about it.原因很简单,让你不得不去思考。 If a std::thread object is destroyed due to an exception escaping the scope then a join may cause a blocking wait during stack unwinding, which is often undesirable, and can lead to deadlock if the thread that is being waited for is in turn waiting for some action on the part of the thread doing the waiting.如果std::thread对象由于超出范围的异常而被销毁,则连接可能会在堆栈展开期间导致阻塞等待,这通常是不可取的,并且如果正在等待的线程依次等待,则可能导致死锁对于执行等待的线程部分的某些操作。

By having the application terminate in this situation you as a programmer are forced to actively think about the conditions that would cause the object to be destroyed, and ensure that the thread is joined correctly.通过在这种情况下终止应用程序,您作为程序员被迫积极考虑会导致对象被销毁的条件,并确保线程正确连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM