c++ - 如何在线程之间传播异常?

标签 c++ multithreading exception

我们有一个单线程调用的函数(我们将其命名为主线程)。在函数体中,我们生成多个工作线程来执行 CPU 密集型工作,等待所有线程完成,然后在主线程上返回结果。

结果是调用者可以天真地使用该函数,并且在内部它将利用多个内核。

到目前为止一切顺利..

我们遇到的问题是处理异常。我们不希望工作线程上的异常导致应用程序崩溃。我们希望函数的调用者能够在主线程上捕获它们。我们必须在工作线程上捕获异常并将它们传播到主线程以让它们继续从那里展开。

我们该怎么做?

我能想到的最好的是:

  1. 在我们的工作线程上捕获各种各样的异常(std::exception 和我们自己的一些异常)。
  2. 记录异常的类型和消息。
  3. 在主线程上有一个相应的 switch 语句,它会重新抛出工作线程上记录的任何类型的异常。

这有一个明显的缺点,即只支持有限的异常类型集,并且每当添加新的异常类型时都需要修改。

最佳答案

C++11 引入了 exception_ptr 类型,允许在线程之间传输异常:

#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept>

static std::exception_ptr teptr = nullptr;

void f()
{
    try
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        throw std::runtime_error("To be passed between threads");
    }
    catch(...)
    {
        teptr = std::current_exception();
    }
}

int main(int argc, char **argv)
{
    std::thread mythread(f);
    mythread.join();

    if (teptr) {
        try{
            std::rethrow_exception(teptr);
        }
        catch(const std::exception &ex)
        {
            std::cerr << "Thread exited with exception: " << ex.what() << "\n";
        }
    }

    return 0;
}

因为在您的情况下,您有多个工作线程,您需要为每个工作线程保留一个 exception_ptr

请注意,exception_ptr 是一个类似 ptr 的共享指针,因此您需要至少保留一个 exception_ptr 指向每个异常,否则它们将被释放。

Microsoft 特定:如果您使用 SEH 异常 (/EHa),示例代码还将传输 SEH 异常,例如访问冲突,这可能不是您想要的。

关于c++ - 如何在线程之间传播异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/233127/

相关文章:

c# - 高性能C# TCP服务器问题: No connection could be made because the target machine actively refused it

c++ - 三个一维或一个二维

c++ - 如何将信号名称(字符串)转换为信号代码?

c++ - 如何保存没有某些字符的字符串?

java - java中静态变量的线程安全

Java基于条件的并发

C++ 为什么这种方式很危险?

c - 原子操作-C

Scala try/catch vs 将来恢复不同的处理异常

c# - 在 .NET 应用程序中使用 Tab 键更改焦点的异常