【问题标题】:C++11: Clang on Mac doesn't catch exception thrown by std::thread function?C++11:Mac 上的 Clang 没有捕获 std::thread 函数抛出的异常?
【发布时间】:2017-08-11 12:48:30
【问题描述】:

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

#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 函数抛出异常,如何捕获/处理它?无法保证线程函数内的代码不会抛出任何异常。

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

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

非常感谢。

【问题讨论】:

  • 如果要将异常传输到调用线程,请使用std::async

标签: multithreading c++11 exception dynamic throw


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    相关资源
    最近更新 更多