std::set_terminate

来自cppreference.com
< cpp‎ | error
在标头 <exception> 定义
(C++11 前)
std::terminate_handler set_terminate( std::terminate_handler f ) noexcept;
(C++11 起)

f 为新的全局终止处理器函数并返回先前安装的 std::terminate_handlerf 应当终止程序的执行而不返回到调用方,否则其行为未定义。

此函数是线程安全的。每次对 std::set_terminate 的调用同步于(见 std::memory_order)后继的 std::set_terminatestd::get_terminate 调用。

(C++11 起)

参数

f - 指向 std::terminate_handler 类型函数的指针,或空指针

返回值

之前安装的终止处理器,或若未安装则为空指针值。

示例

#include <cstdlib>
#include <exception>
#include <iostream>
 
int main()
{
    std::set_terminate([]()
    {
        std::cout << "Unhandled exception\n" << std::flush;
        std::abort();
    });
    throw 1;
}

可能的输出:

Unhandled exception
bash: line 7:  7743 Aborted                 (core dumped) ./a.out

终止处理器函数也作用于启动的线程,因此,可以将它用作把线程函数包装到 try/catch 块中的另一种方式。以下示例中,由于异常未被处理,将会调用 std::terminate

#include <iostream>
#include <thread>
 
void run()
{
    throw std::runtime_error("线程失败");
}
 
int main()
{
    try
    {
        std::thread t{run};
        t.join();
        return EXIT_SUCCESS;
    }
    catch (const std::exception& ex)
    {
        std::cerr << "异常:" << ex.what() << '\n';
    }
    catch (...)
    {
        std::cerr << "捕获到未知异常\n";
    }
    return EXIT_FAILURE;
}

可能的输出:

terminate called after throwing an instance of 'std::runtime_error'
  what():  线程失败
Aborted (core dumped)

引入终止处理器后,从非主线程中抛出的异常都可以被分析,并且可以进行优雅的退出。

#include <iostream>
#include <thread>
 
class foo
{
public:
    foo() { std::cerr << "foo::foo()\n"; }
    ~foo() { std::cerr << "foo::~foo()\n"; }
};
 
// 静态对象,预期退出时执行析构函数
foo f;
 
void run()
{
    throw std::runtime_error("线程失败");
}
 
int main()
{
    std::set_terminate([]()
    {
        try
        {
            std::exception_ptr eptr{std::current_exception()};
            if (eptr)
            {
                std::rethrow_exception(eptr);
            }
            else
            {
                std::cerr << "无异常退出\n";
            }
        }
        catch (const std::exception& ex)
        {
            std::cerr << "异常: " << ex.what() << '\n';
        }
        catch (...)
        {
            std::cerr << "捕获到未知异常\n";
        }
        std::exit(EXIT_FAILURE);
    });
 
    std::thread t{run};
    t.join();
}

输出:

foo::foo()
异常:线程失败
foo::~foo()

参阅

异常处理失败时调用的函数
(函数)
获得当前的 terminate_handler
(函数)
std::terminate 所调用的函数类型
(typedef)