【问题标题】:C++ program return code when std::terminate is called in thread [closed]在线程中调用 std::terminate 时 C++ 程序返回代码 [关闭]
【发布时间】:2017-05-10 15:31:52
【问题描述】:

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

我知道在很多情况下使用std::thread 并不是一个聪明的主意,我计划转而使用std::async(或类似的),但目前我对快速解决这个问题很感兴趣。

【问题讨论】:

  • 这是你的程序。您可以完全控制其退出状态。
  • 你能展示 MCVE 吗?
  • 应该这样做(std::terminate 调用std::abort):“实现定义的状态返回到主机环境,表明执行不成功。”我们需要@987654321 @+ 平台详情。见:en.cppreference.com/w/cpp/utility/program/abort

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


【解决方案1】:

好吧,认为我很愚蠢。该程序正确返回了一个错误代码,但是当我将输出(它写入大量日志)通过管道传输到tee 时,存储在$? 中的返回代码可能是tee 中的一个,它没有失败地退出。

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

【讨论】:

  • 认为自己很聪明 :) 通过仔细检查自己所做的事情,您找出了问题的真正原因。
【解决方案2】:

正如 Richard Critten 在评论中指出的那样,std::terminate() 调用 std::abort(),但这还不是全部。

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 处理程序并使用所需的退出代码退出程序。但在这种情况下,不会进行任何资源清理。

【讨论】:

    【解决方案3】:

    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 状态退出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-05
      • 2010-09-30
      相关资源
      最近更新 更多