【问题标题】:In which thread is the terminate handler called?终止处理程序在哪个线程中调用?
【发布时间】:2017-11-01 13:08:50
【问题描述】:

在哪个线程中调用终止处理程序:

  1. noexcept 函数内部抛出异常时?

  2. 当用户调用std::terminate()时?

  3. thread 的启动或销毁?

它是否在标准中定义,我可以访问thread_local 对象吗?

【问题讨论】:

  • 我的常识告诉我它会在名为std::terminate的线程上调用?我确实相信标准没有明确解决这个问题。
  • 我认为这是未指定的行为(或者可能未定义?)
  • 我无法想象有某种机制可以中断任何其他线程可能正在执行的操作以使其运行std::terminate。我认为调用std::terminate 的线程可以运行它。
  • 让代码在特定的其他线程上运行是非常不平凡的。所以它只是没有,它运行在任何遭受心脏病发作的线程上。易于自己尝试,让您感觉更好。
  • 我刚查了在线编译器,终止的线程是调用std::terminate的线程。

标签: c++ terminate terminate-handler


【解决方案1】:

这个答案总结了 cmets 中给出的答案,现在删除了一个答案:

  • 标准中没有规定(DeiDei,我在N4618也查过)

  • 尽管如此,由于技术原因,处理程序不太可能在另一个线程中调用,而不是导致调用 std::terminate 的线程(GalikHans Passant)

  • 已在在线编译器 (Rinat Veliakhmedov) 上验证,终止处理程序在导致终止被调用的线程中被调用。

您可以使用已删除答案中的此代码自行测试:

#include <string>
#include <exception>
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mutex;
const auto& id = std::this_thread::get_id;
const auto print = [](std::string t){
    std::lock_guard<std::mutex> lock(mutex);
    std::cout << id() << " " << t << std::endl;
};

void my_terminate_handler(){
    print("terminate");
    std::abort();
}

void throwNoThrow() noexcept { throw std::exception(); }
void terminator()            { std::terminate();       }

int main() {
    std::set_terminate(my_terminate_handler);
    print("main");    
#ifdef  CASE1
    auto x1 = std::thread(throwNoThrow);
#elif CASE2
    auto x1 = std::thread(terminator);
#elif CASE3    
    auto x1 = std::thread(throwNoThrow);
#endif
    x1.join();
}

结论未指定,但似乎总是在导致调用std::terminate 的线程中调用处理程序。 (在 gcc-5.4、gcc-7.1、clang-3.8 和 pthreads 上测试

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 2019-01-26
    • 2012-04-29
    • 1970-01-01
    相关资源
    最近更新 更多