2011-01-22 53 views
3

因此,我对pthread_exitpthread_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> 

谢谢!

埃里克

回答

4

还请注意,我打电话 了pthread_exit我的SIGTERM信号 处理程序。

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

如果发生不是调用中止()的结果的其它信号,提高(),kill(),pthread_kill()或sigqueue(),行为未定义如果信号处理程序引用具有静态存储持续时间的任何对象,而不是通过将值分配给声明为易失性sig_atomic_t的对象,或者如果信号处理程序调用标准库中的任何函数,而不是信号概念中列出的函数之一。

的允许功能列表在http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03给出,并且不包括pthread_exit()。因此你的程序显示未定义的行为。

我能想到的三个选择:

  1. 在由线程定期检查,而不是试图直接从信号处理程序退出信号处理程序设置一个标志。
  2. 使用sigwait()明确地等待独立线程上的信号。然后该线程可以在您希望退出的线程上显式调用pthread_cancel()
  3. 屏蔽信号,并定期在要退出的线程上调用sigpending(),如果信号处于挂起状态,则退出。
相关问题