未处理的强制展开会导致中止

Eri*_*ric 4 c++ exception pthreads terminate abort

因此,我对两者pthread_exit和的理解pthread_cancel是,它们和两者都会导致被称为“强制展开”的异常类东西从目标线程中的相关堆栈帧中抛出。可以捕获此异常以进行特定于线程的清理,但是必须重新抛出该异常,否则我们会abort()在未重新抛出的catch块末尾得到一个隐式。

在的情况pthread_cancel下,根据线程的取消状态和类型,这可能在接收到相关信号后立即发生,或者在下一次进入取消点时发生,或者在下一次解除阻止该信号时发生。

在的情况下pthread_exit,调用线程立即进行强制展开。

精细。此“例外”是杀死线程的正常过程。那么,为什么即使我重新抛出它,也会导致它std::terminate()被调用而中止整个应用程序?

请注意,我捕获并重新抛出了几次异常。

还需要注意的是我打电话给pthread_exit我的了SIGTERM信号处理程序。在我用g ++ 4.3.2编译的玩具测试代码中,这可以很好地工作,该代码先运行一个线程signal(SIGTERM, handler_that_calls_pthread_exit),然后紧密while循环直到获得TERM信号。但这在实际应用程序中不起作用。

相关堆栈帧:

(gdb) where
#0  0x0000003425c30265 in raise () from /lib64/libc.so.6
#1  0x0000003425c31d10 in abort () from /lib64/libc.so.6
#2  0x00000000012b7740 in sv_bsd_terminate () at exception_handlers.cpp:38
#3  0x00002aef65983aa6 in __cxxabiv1::__terminate (handler=0x518)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:43
#4  0x00002aef65983ad3 in std::terminate ()
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:53
#5  0x00002aef65983a5a in __cxxabiv1::__gxx_personality_v0 (
    version=<value optimized out>, actions=<value optimized out>, 
    exception_class=<value optimized out>, ue_header=0x645bcd80, 
    context=0x645bb940)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libstdc++-v3/libsupc++/eh_personality.cc:657
#6  0x00002aef6524d68c in _Unwind_ForcedUnwind_Phase2 (exc=0x645bcd80, 
    context=0x645bb940)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libgcc/../gcc/unwind.inc:180
#7  0x00002aef6524d723 in _Unwind_ForcedUnwind (exc=0x645bcd80, 
    stop=<value optimized out>, stop_argument=0x645bc1a0)
    at /view/ken_gcc_4.3/vobs/Compiler/gcc/libgcc/../gcc/unwind.inc:212
#8  0x000000342640cf80 in __pthread_unwind () from /lib64/libpthread.so.0
#9  0x00000034264077a5 in pthread_exit () from /lib64/libpthread.so.0
#10 0x0000000000f0d959 in threadHandleTerm (sig=<value optimized out>)
    at osiThreadLauncherLinux.cpp:46
#11 <signal handler called>
Run Code Online (Sandbox Code Playgroud)

谢谢!

埃里克

Ant*_*ams 6

还要注意,我是从SIGTERM信号处理程序中调用pthread_exit的。

这是你的问题。引用POSIX规范(http://pubs.opengroup.org/onlinepubs/009695399/functions/signal.html):

如果信号不是通过调用abort(),raise(),kill(),pthread_kill()或sigqueue()的结果发生的,如果信号处理程序引用具有除静态存储持续时间以外的任何对象的行为,则 该行为未定义通过为声明为volatile sig_atomic_t的对象分配值,或者信号处理程序调用标准库中除Signal Concepts中列出的功能之一以外的任何功能。

允许的功能列表在http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03上提供,但不包括pthread_exit()。因此,您的程序表现出不确定的行为。

我可以想到三个选择:

  1. 在信号处理程序中设置一个标志,该标志由线程定期检查,而不是尝试直接从信号处理程序中退出。
  2. 使用sigwait()显式地等待在独立的线程的信号。然后,该线程可以显式调用pthread_cancel()您要退出的线程。
  3. 屏蔽信号,并sigpending()在要退出的线程上定期调用,如果信号未决,则退出。