在线程中调用std :: terminate时的C ++程序返回码

时间:2017-05-10 15:31:52

标签: c++ multithreading bash c++11 exit-code

我有一个程序,它创建使用std::thread个对象同时执行工作。我从bash脚本调用程序,如果程序没有以EXIT_SUCCESS终止,则想要停止脚本。在以下情况下,我遇到了一种非直观的行为:其中一个线程抛出异常(因此调用std::terminate),导致程序完全终止。但是,程序的返回码是EXIT_SUCCESS(而不是我期望的一些错误代码)。那是为什么?

我知道在许多情况下使用std::thread并不是一个聪明的主意,我打算转移到std::async(或类似),但此刻,我对a感兴趣快速解决这个问题。

3 个答案:

答案 0 :(得分:1)

好吧,我觉得我很蠢。程序正确返回错误代码,但是当我将输出(它写入大量日志)传送到tee时,存储在$?中的返回码可能是tee中的一个,退出而没有失败。

[编辑]我现在正在使用PIPESTATUS来获取正确的退出代码。

答案 1 :(得分:1)

正如理查德·克里滕在评论std::terminate()中提到std::abort()所指出的那样,但并非全部。{/ p>

C ++提供了很多控制这种情况的机制。我可以建议的是:

使用std::set_terminate()

std::terminate()的来电注册您自己的处理程序
#include <iostream>
#include <cstdlib>
#include <exception>

int main()
{
    std::set_terminate
    ( []()
      { 
        std::cout << "Unhandled exception\n";
        std::exit(EXIT_FAILURE);
      }
    );

    throw 1;
}

调用std::exit()会导致程序正常终止并执行一些清理步骤。

另一种选择是注册SIGABORT处理程序并使用所需的退出代码退出程序。但在这种情况下,没有资源清理。

答案 2 :(得分:0)

C ++ 11具有exception_ptr类型,允许在线程之间传输异常。因此,如果您想处理异常,可以考虑以下方法。

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

static std::exception_ptr eptr = nullptr;

void foo()
{
    try
    {
        ....
        throw std::runtime_error("Bla bla"); // put your exception instead of runtime_error
    }
    catch(...)
    {
        eptr = std::current_exception();
    }
}

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

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

        }
    }

    return EXIT_SUCCESS;
}

如果线程抛出异常,此方法将确保程序将以状态EXIT_FAILURE退出。