C++11:Mac 上的 Clang 没有捕捉到 std::thread 函数抛出的异常?

C++11: Clang on Mac doesn't catch exception thrown by std::thread function?

我有一个非常简单的程序:

#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+clang 环境中,运行 结果是:

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

它没有像我预期的那样打印 "N dtor"。所以我的问题是,如果 std::thread 函数抛出异常,如何使用它 catch/deal?不能保证线程函数中的代码不会抛出任何异常。

我在linux上试过了,异常可以被捕获并打印:

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

非常感谢。

如果在线程中抛出异常,则必须在同一个线程中捕获(或根本不捕获)。在您的示例中,try 块可以捕获专门来自尝试创建或加入线程的异常,但不能捕获由线程中的代码 运行 引起的异常。

如果你仔细想想,这就是它必须的样子。您的示例试图确保您在线程完成之前不会离开 try 块,但这通常不能保证。即使在您的示例中,if 连接调用试图抛出源自目标线程的异常(它们没有,但为了论证...),您永远不会到达 join(b) 调用,当 b 的线程抛出异常时,没有什么能保证您仍在 try 块中。

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