【问题标题】:C++ exception not being handled in thread线程中未处理 C++ 异常
【发布时间】:2014-09-10 09:23:58
【问题描述】:

为什么 VS 2013 没有给出unhandled exception 异常,或者在执行以下代码时引发任何中止信号?

#include <thread>

void f1()
{
    throw(1);
}

int main(int argc, char* argv[])
{
    std::thread(f1);
}

C++ 标准规定 std::terminate 应在以下情况下调用:

when the exception handling mechanism cannot find a handler for a thrown exception (15.5.1)

in such cases, std::terminate() is called (15.5.2)

【问题讨论】:

  • @user657267 不是真的。我不想在线程之间传播异常,我想知道为什么上面的代码正常执行并终止而没有引发异常。
  • 你既没有加入也没有脱离那个线程,所以很确定你有未定义的行为。 (而且你的程序可能在线程真正有机会运行之前就退出了。)
  • @Mat 谢谢,我真是个白痴。您为什么不将其作为答案提交,以便我标记为答案?
  • 嗯,我不太确定。似乎你仍然应该得到一个terminate,因为当你退出 main 时,该线程对象应该是活动的,调用线程的析构函数。如果线程是可连接的,那么调用就会终止。 clang 和 GCC 调用都在此处终止 (Linux)。

标签: c++ exception visual-studio-2013


【解决方案1】:

问题在于,在这段代码中,main() 可能在生成的线程 (f1) 之前结束。

试试这个:

#include <thread>

void f1()
{
    throw(1);
}

int main(int argc, char* argv[])
{
    std::thread t(f1);
    t.join(); // wait for the thread to terminate
}

在 Coliru (gcc) 上调用 terminate()。

不幸的是,Visual Studio 2013 在遇到这种情况时将直接调用 abort() 而不是 terminate() (至少在我的测试中),因此即使添加处理程序(使用 std::set_handler() )显然也不起作用。 I reported this to the VS team.

不过,此代码将触发错误,而您的初始代码不保证。

【讨论】:

  • 对 abort 的调用将对应于默认行为(参见 18.8.3.1. pt 3),但我确认您的测试:使用 set_terminate() 设置终止处理程序时(如 std, 18.8.3.2 中所定义),则不调用处理程序。并且 set_unexpected() (std. D.11) 也被忽略了
  • @Christophe 是的,问题是对 abort() 的调用是在抛出点完成的,而不是在默认终止处理程序或任何处理程序中。在这种情况下不应该调用意外的处理程序,因为如果我理解正确的话,会有异常规范。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2011-01-29
  • 1970-01-01
相关资源
最近更新 更多