2011-12-07 8 views
1

내가 좋아하는 SIGCHLD 핸들러의 몇 가지 예를 참조 다시 설치SIGCHLD 핸들러는

void child()                             
{                              
    wait(0);                           
    signal(SIGCHLD, child);  
} 
void server_main() 
{ 
    ... 
    signal(SIGCHLD, child); 
    ... 
    for(;;;) { 
     ... 
     switch(fork()) { 
     ... 
     } 
    } 

이 저를 혼동 핸들러의 두 부분 : 1). SIGCHLD는 자식이 종료되거나 중지 될 때 잡힌다. 그럼 처리기 안에서 기다려야하는 이유는 무엇입니까? 신호가 이미 도착했습니다. 2). 왜 SIGCHLD 핸들러를 다시 설치해야합니까? 신호 호출이 처리기를 한 번만 설치하는 것이 아닌가?

감사합니다.

답변

2
  1. 자식 프로세스가 실행을 완료하면 SIGCHLD가 트리거됩니다. 그러나 부모가 자식의 값인 값을 가져 오도록 프로세스 테이블 ( 소위 좀비 프로세스)에 계속 남아 있습니다. wait()을 호출하면 하위 프로세스의 프로세스 테이블 이 지워집니다.
  2. 자식 프로세스가 n 인 경우에만 n 자식 프로세스가 모두 종료 될 때 신호 처리기가 계속 작동 할 이유가 없습니다.

대신에 signal의 동작이 Unix간에 달라 지므로 sigaction을 살펴 보시기 바랍니다.

+0

감사합니다. 첫 번째 부분을 봅니다. 두 번째의 경우 신호 처리기가 상위 권한에 설치되어 있습니까? 왜 여러 자식 프로세스가 죽었을 때 신호 처리기가 효과가 없을 수 있습니까? – Oxdeadbeef

+0

설명을 sarnold 님이 보시고, 꽤 잘 설명해 주셨습니다. – halfdan

1

신호 호출이 처리기를 한 번만 설치하겠습니까?

이 동작은 신뢰할 수 없습니다. 아마 신호 처리기가 지워질 것입니다. 이것은 역사적인 신호 처리 문제의 일부입니다. 내 시스템 보고서에 signal(3) 맨 :

When a signal occurs, and func points to a function, it is 
    implementation-defined whether the equivalent of a: 


      signal(sig, SIG_DFL); 

    is executed or the implementation prevents some 
    implementation-defined set of signals (at least including 
    sig) from occurring until the current signal handling has 
    completed. 

신뢰할 수없는 신호는 거의 sigaction(2) 기반 신호 POSIX.1-2001에 SysVr4 도입 및 표준화에 의해 대체되었습니다 :

struct sigaction { 
     void  (*sa_handler)(int); 
     void  (*sa_sigaction)(int, siginfo_t *, void *); 
     sigset_t sa_mask; 
     int  sa_flags; 
     void  (*sa_restorer)(void); 
    }; 

    int sigaction(int signum, const struct sigaction *act, 
       struct sigaction *oldact); 

이 슬프게도 더 복잡 코드를 작성한 후에는 처리기를 다시 설치해야하는지 궁금 할 필요가 없으며 신호를 처리하는 동안 신호가 두 번째로 도착할 것을 염려 할 필요가 없습니다 .