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
块中。
一个线程捕获另一个线程的异常的流程控制根本不起作用。如果您需要这种功能,您可以在工作线程中放置一个异常处理程序,并让它使用已建立的线程间通信机制将异常状态传回主线程。
我有一个非常简单的程序:
#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
块中。
一个线程捕获另一个线程的异常的流程控制根本不起作用。如果您需要这种功能,您可以在工作线程中放置一个异常处理程序,并让它使用已建立的线程间通信机制将异常状态传回主线程。