2011-01-22 71 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(),如果信號處於掛起狀態,則退出。