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

C++ 可连接std::thread不能自动连接的原因是什么?,c++,multithreading,c++11,thread-safety,language-lawyer,C++,Multithreading,C++11,Thread Safety,Language Lawyer,有时,如果一个可连接的std::thread能够在其析构函数上执行thread::join(),它会很有用。请参见下面的示例 示例1(错误): 抛出异常后,对象std::thread已被销毁。一旦流退出作用域,就会在连接发生之前调用析构函数。它使STL显示“中止”的错误消息 int main( int argc, const char * argv[] ) { try { thread t( [] () { this_thr

有时,如果一个可连接的
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;
}
…问题是: 可连接的
std::thread
不能在其析构函数上自动连接的原因是什么

如果它是自动发生的,那就容易多了。今天的做法要求在try-catch块中使用线程时必须小心,例如。。。但是我确信当设计
std::thread
时,有人会这样想。所以这一定是有原因的。。。这是什么原因


PS:我知道我们可以在类中envolve
std::thread
并将
join()
放在这个新类的析构函数上。。。所以它变成自动的。但这不是重点。我的问题实际上是关于std::thread本身的。

原因很简单,你不得不考虑它。如果
std::thread
对象由于超出作用域的异常而被销毁,那么连接可能会在堆栈展开期间导致阻塞等待,这通常是不可取的,并且如果正在等待的线程依次等待执行等待的线程的某个操作,则可能导致死锁


通过让应用程序在这种情况下终止,作为程序员,您必须积极考虑可能导致对象被破坏的条件,并确保线程正确连接。

关注点分离。如果您想要一个启动线程并在销毁时等待其完成的东西,请编写它。请注意,上面的代码不能保证
join()
发生。在C++中,可以抛出任何类型的值,它不必从 STD::在C++中,如果需要保证某些动作发生(是否抛出异常),请使用RIIAL句柄,其中在析构函数中发生清理。但我明白你的意思。是的-听起来像是关闭失败的完美例子。“如果std::thread对象由于超出作用域的异常而被破坏,那么连接可能会在堆栈展开期间导致阻塞等待”-我不明白:如果std::thread对象已经被破坏,那么还有什么可以调用它的连接呢?你能详细说明一下吗?
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;
}