相关疑难解决方法(0)

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

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

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

到目前为止都很好..

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

我们应该怎么做?

我能想到的最好的是:

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

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

c++ multithreading exception

103
推荐指数
5
解决办法
4万
查看次数

工作线程中的C++未捕获异常

未捕获的异常对主线程和另一个std :: thread的行为有所不同.

这是测试程序

#include <thread>

class XXX{
public:
  XXX(){std::fprintf(stderr, "XXX ctor\n");}
  ~XXX(){std::fprintf(stderr, "XXX dtor\n");}
};

void mytest(int i)
{
    XXX xtemp;
    throw std::runtime_error("Hello, world!");
}
int main(int argc, char *argv[])
{
    if(argc == 1) {
        mytest(0);
    }else{
        std::thread th([&]{mytest(0);});
        th.join();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码(C++ 11),由GCC 5.4编译运行,没有args

XXX ctor
terminate called after throwing an instance of 'std::runtime_error'
   what():  Hello, world!
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

运行1 arg:

XXX ctor
XXX dtor
terminate called after throwing an instance of 'std::runtime_error'
  what():  Hello, world!
Aborted …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading stack-unwinding uncaught-exception

5
推荐指数
1
解决办法
553
查看次数

boost::asio::co_spawn 不会传播异常

我正在涉足关于 boost::asio 的协程,并且我对异常处理感到困惑。从文档中的示例 来看,看起来任何“失败”都会变成异常 - 所以我希望假设抛出的任何异常也会传播回调用。但情况似乎并非如此:error_codeco_spawn

#define BOOST_ASIO_HAS_CO_AWAIT
#define BOOST_ASIO_HAS_STD_COROUTINE

#include <iostream>

#include <boost/asio/awaitable.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/executor_work_guard.hpp>

namespace this_coro = boost::asio::this_coro;

boost::asio::awaitable<void> async_op()
{
    std::cout << "About to throw" << std::endl;
    throw std::runtime_error{"Bang!"};
}

int main()
{
    auto ctx = boost::asio::io_context{};
    auto guard = boost::asio::make_work_guard(ctx.get_executor());

    boost::asio::co_spawn(ctx, async_op, boost::asio::detached);

    ctx.run();
}
Run Code Online (Sandbox Code Playgroud)

如果这是在调试器中运行,您可以看到抛出异常,但它似乎只是挂起。暂停调试器表明正在ctx.run()等待新的工作(由于executor_work_guard)。所以看起来 boost::asio 内部的某些东西已经默默地吞噬了异常。

作为实验,我将异步操作切换为使用 boost::asio 库调用:

boost::asio::awaitable<void> async_op()
{
    auto executor = co_await this_coro::executor;
    auto …
Run Code Online (Sandbox Code Playgroud)

c++ boost exception coroutine

5
推荐指数
1
解决办法
1359
查看次数