std :: thread和异常处理

时间:2016-12-29 04:13:43

标签: c++ multithreading exception

我在处理多线程c ++代码中的异常时遇到问题。以下程序以terminate called without an active exception Aborted (core dumped)退出。

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

struct Thing {

    void runComponent()
    {
       throw std::runtime_error("oh no!\n");
    }

    void runController()
    {
        while (true) {}
    }

    void run()
    {
        auto control_thread = std::thread([this] { runController(); });

        runComponent();

        if (control_thread.joinable())
            control_thread.join();
    }
};

int main() 
{
    try {
        Thing thing;
        thing.run();
    } catch (std::runtime_error &ex) {
        std::cerr << ex.what();
    }
}

相反,我想在try catch的{​​{1}}块中处理异常。我知道异常不会(通常)在线程之间传递,因为每个线程都有自己的堆栈。这里的问题(在我看来)是异常没有被处理,即使它是在非分叉线程上生成的。如果我在main()注释run()中与control_thread有关的行,那么一切正常。

使用clang-3.8和-std=c++11 main.cpp -lpthread编译。

1 个答案:

答案 0 :(得分:2)

这里的问题是您在detach()方法中创建的主题上没有调用join()run()。这是C ++线程中的错误。见When should I use std::thread::detach?

如果您将代码更改为以下任一项,那么一切正常

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

struct Thing {

    void runComponent()
    {
       throw std::runtime_error("oh no!\n");
    }

    void runController()
    {
        return;
    }

    void run()
    {
        auto control_thread = std::thread([this] { runController(); });
        // either of the following two will work
        // control_thread.join();
        control_thread.detach();

        runComponent();
    }
};

int main()
{
    try {
        Thing thing;
        thing.run();
    } catch (std::runtime_error &ex) {
        std::cerr << ex.what();
    }
}

看起来你想要的是一个分离,这就是我在上面的例子中分离线程的原因。如果这不是你想要的,你可能需要一些其他方法来处理线程的join()。如果您希望主线程和其他线程独立运行,那么您将需要一些其他同步。