2017-08-11 61 views
-1

我有一个非常简单的程序为:C++ 11:Mac上的Clang不会捕获std :: thread函数抛出的异常?

#include <iostream> 
#include <string> 
#include <thread> 
using namespace std; 
struct N{ 
    string s; 
    N(){} 
    ~N(){cout<<"N dtor"<<endl;} 
}; 

void f(){ 
    N n; 
    throw 0; 
} 
int main(){ 
    try{ 
     thread a(f), b(f); 
     a.join(); 
     b.join(); 
    }catch(exception& e){ 
     cout<<e.what()<<endl; 
    } 
    return 0; 
} 

在我的Mac +铛环境,运行结果是:

libc++abi.dylib: terminating with uncaught exception of type int 
Abort trap: 6 

它不打印“N析构函数”,因为我预期。所以我的问题,如果std :: thread函数抛出一个异常,如何捕捉/处理它?不能保证线程函数内的代码不会抛出任何异常。

我试图在Linux和异常可以被捕获并打印:

Enable multithreading to use std::thread: Operation not permitted 

非常感谢。

+0

如果您想将异常传输到调用线程,请使用'std :: async'。 – ecatmur

回答

2

如果在线程中抛出异常,它必须被捕获到同一个线程中(或者根本没有)。在您的示例中,try块可以特别从创建或加入线程的尝试中捕获异常,但不会捕获线程中运行的代码导致的异常。

如果你仔细想想,这就是它的原因。你的例子试图确保你不会离开try块,直到线程完成,但这通常不能得到保证。即使在你的例子中,如果连接调用试图抛出源于目标线程的异常(它们没有,但为了争论...),你永远不会达到join(b)调用,并且没有什么可以保证当b的线程抛出异常时,您仍然位于try块中。

一个线程的流量控制捕捉另一个线程的异常根本不起作用。如果您需要这种功能,您可以在工作线程中放置一个异常处理程序,并使用已建立的线程间通信机制将异常状态通知给主线程。