Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
370 views
in Technique[技术] by (71.8m points)

c++ - 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. See the examples below.

Example 1 (error): The object std::thread has been destroyed after the throw of the exception. Once the the flow exits the scope, the destructor is called BEFORE the join happens. It makes STL show an error message of 'abort'.

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. So it guarantees that the join() happens.

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?

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. 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. But this is not the point. My question is really about std::thread itself.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...