C++ C++;未捕获异常,程序终止并中止

C++ C++;未捕获异常,程序终止并中止,c++,multithreading,exception,stack-unwinding,C++,Multithreading,Exception,Stack Unwinding,此程序在捕获异常处理程序之前终止 void main(){ try{ work1(); std::thread joinableThread( [](){ work2(); } ); work3(); throw std::runtime_error("catch me if you can"); joinableThre

此程序在捕获异常处理程序之前终止

void main(){
    try{

       work1();

       std::thread joinableThread(
           [](){
               work2();
           }
       );

       work3();

       throw std::runtime_error("catch me if you can");

       joinableThread.join();

    } catch(const std::runtime_error& ex){
       std::cout << "You did it!" << std::endl;
    }
}
void main(){
试一试{
工作1();
std::线程可连接线程(
[](){
工作2();
}
);
工作3();
抛出std::runtime_错误(“如果可以,请抓住我”);
joinableThread.join();
}捕获(const std::runtime_error&ex){

std::cout我认为在堆栈展开期间加入线程是个坏主意。暂停析构函数直到将来发生不受控制的事件,这使得应用程序很难推理

我相信,这是
std::thread
destructor抛出而不是加入线程的原因之一

现在,回答你的问题

第一种解决方案是uber simple-wrap
std::thread
,它在您自己的对象中调用
join
它是析构函数。我认为,出于上述原因,这不是一种很好的方法

第二个选择是做另一个包装器对象——在它的析构函数中分离线程的对象。在我看来,这是更好的选择,但是你显然有一个线程的问题,它现在无法连接并等待完成


为了缓解这种情况,您可以通过您选择的任何机制来增强线程以发出完成信号,然后等待该信号(从分离的线程发出信号)。但是,如果本地线程使用将在堆栈展开期间被销毁的对象,这仍然会出现问题。我看不到解决此问题的好方法。

使用析构函数的虚拟对象,该析构函数连接线程?请参阅:在
try
外部创建线程对象,在
try
内部初始化它,然后在
catch
中,检查它是否可连接,然后
join
它?两个选项:a)在try块之外创建线程(编辑:这是前面的评论者建议的内容)b)而不是
std::thread
使用在销毁时连接的变体,例如