2011-01-22 5 views
3

pthread_exitpthread_cancel을 모두 이해할 경우 대상 스레드의 관련 스택 프레임에서 "forced unwind"라는 예외와 비슷한 결과가 발생합니다. 이것은 특정 스레드 정리를 수행하기 위해 발견 될 수 있지만 다시 throw되어야합니다. 그렇지 않으면 다시 throw하지 않는 catch 블록의 끝에 암시적인 abort()이 표시됩니다.처리되지 않은 강제 unwind cause abort

pthread_cancel의 경우 스레드의 취소 상태 및 유형에 따라 신호가 수신 될 때 즉시 또는 취소 지점에 다음 항목이 생기거나 다음에 신호가 차단 해제 될 때 발생합니다.

pthread_exit의 경우 호출 스레드가 즉시 강제 unwind됩니다.

좋아요. 이 "예외"는 스레드를 죽이는 과정의 정상적인 부분입니다. 그렇다면 다시 던지더라도 std::terminate()이 호출되어 전체 응용 프로그램을 중단하는 이유는 무엇입니까?

나는 예외를 몇 번 붙잡고 다시 던지고 있음에 유의하십시오.

SIGTERM 신호 처리기를 호출하고 있습니다. g ++ 4.3.2로 컴파일 된 내 장난감 테스트 코드에서이 작업은 스레드가 signal(SIGTERM, handler_that_calls_pthread_exit)으로 실행 된 다음 TERM 신호가 도착할 때까지 단단한 while 루프에 앉아 있습니다. 그러나 실제 응용 프로그램에서는 작동하지 않습니다.

관련 스택 프레임 :

(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> 

감사합니다!

에릭 내 SIGTERM 신호 핸들러에서 는 pthread_exit를 호출하고있어 것 또한

답변

4

참고.

이것은 사용자의 문제입니다. POSIX의 사양 (http://pubs.opengroup.org/onlinepubs/009695399/functions/signal.html)에서 인용하면 신호가 중단()를 호출의 결과로 이외 발생하는 경우

인상(), kill(), pthread_kill() 또는 sigqueue(), 신호 처리기가 정적 저장 기간이있는 객체를 참조하는 경우 동작이 정의되지 않음 volatile 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()을 주기적으로 호출하고 신호가 보류중인 경우 종료하십시오.