2013-11-09 2 views
1

나는 그들 각각 (SIGTSTP, SIGCHLD)에 대해 견인 핸들러를 가지고있다. 문제는 SIGTSTP를 사용하여 프로세스를 멈추었을 때 SIGCHLD의 핸들러 기능 역시 실행된다는 것이다. 이것을 막기 위해 무엇을해야합니까?
SIGTSTP와 SIGCHLD 사이의 관계

신호 처리기 :

void signalHandler(int signal) { 
int pid, cstatus; 
if (signal == SIGCHLD) { 
    susp = 0; 
    pid = waitpid(-1, &cstatus, WNOHANG); 
    printf("[[child %d terminated]]\n", pid); 
    DelPID(&JobsList, pid); 
} 
} 

void ctrlZsignal(int signal){ 
    kill(Susp_Bg_Pid, SIGTSTP); 
    susp = 0; 
    printf("\nchild %d suspended\n", Susp_Bg_Pid); 
} 

중지 된 프로세스 아이디를 저장하는 데 사용 Susp_Bg_Pid.
susp는 일시 중단되었거나 중지 된 경우 상위 프로세스의 "스매시"상태를 나타냅니다.

+0

오른쪽 플래그를 사용하면 일시 중지 된 아이와 수신 한 신호를 알 수 있습니다. 따라서 실제 이탈을 감지 할뿐만 아니라 일시 중지/다시 시작을위한 조치를 취할 수도 있습니다. –

답변

2

sigactionSA_NOCLDSTOP을 사용하여 SIGCHLD 처리기를 설정하십시오. 은 sigaction에서

(2)

SA_NOCLDSTOP - 부호 요소가 SIGCHLD이면 자식 프로세스가 중지되면, 알림을받지 않습니다 (즉, 그들은 SIGSTOP, SIGTSTP, SIGTTIN 또는 SIGTTOU 중 하나가 나타날 경우) 또는 이력서 (즉, , 그들은 SIGCONT를 받는다 (wait (2)를 보라). 이 플래그는 SIGCHLD에 대한 핸들러를 설정할 때만의 L가 있습니다.

갱신

void signalHandler(int sig) 
{ 
    //... 
} 

struct sigaction act; 

act.sa_handler = signalHandler; 
sigemptyset(&act.sa_mask); 
act.sa_flags = SA_NOCLDSTOP; 

if (sigaction(SIGCHLD, &act, 0) == -1) 
{ 
    perror("sigaction"); 
    exit(1); 
} 

당신이 signal에 훨씬 우수하지만, 비용에 와서 여러 가지 옵션과 행동을 가지고 있기 때문에 당신이 그것을 읽어해야 sigaction에 익숙하지 않은 경우 복잡성과 혼란을 사전에 파악해야합니다. 나는 당신이하고 싶은 것의 최소한으로 내 최선의 추측을 취했으나, 나중에보다는 오히려 이것을 빨리 배워야 할 것입니다.

+0

예를 들어 줄 수 있습니까? 감사합니다 – Rawhi

+0

BTW, SA_NOCLDSTOP은 * nix 플랫폼에서 사용할 수 있지만 구현에 따라 다르며 모든 플랫폼에서 예상대로 작동하지 않을 수 있습니다. 그것은 리눅스에서 작동합니다. – Duck