因此,我对pthread_exit
和pthread_cancel
的理解是,它们都会导致类似异常的事件被称为“强制展开”,从目标线程中的相关堆栈帧中抛出。这可以被捕获以便进行特定于线程的清理,但必须重新抛出,否则我们会在catch块的末尾获得一个隐式abort()
,而不会重新抛出。
在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>
谢谢!
埃里克
答案 0 :(得分:4)
另请注意我正在打电话 pthread_exit来自我的SIGTERM信号 处理程序。
这是你的问题。引用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()
。因此,您的程序表现出不确定的行为。
我可以想到三个选择:
sigwait()
显式等待独立线程上的信号。然后,该线程可以在您要退出的线程上显式调用pthread_cancel()
。sigpending()
,如果信号未决,则退出。