2009-03-10 3 views

답변

4

신호 처리는 프로세스에 대해 전체적으로 설정됩니다. 일부 자식은 종료되지만 다른 자식은 종료하지 않을 때 SIGCHLD와 같은 비동기 신호를 잡으려면 미리 무시해도됩니다.

부모에서 신호를 처리하고 처리기에서 신호를 무시할지 여부를 결정해야합니다.

최소한 핸들러는 리턴 코드를 얻기 위해 자식 (siginfo_t 구조의 si_pid)에 wait()를 수행해야합니다. 이 시점에서 프로세스 ID를 확인하고 그 밖의 작업을 결정할 수 있습니다. 원하지 않으면 아무것도 인쇄 할 필요가 없습니다.

0

SIGCHLD를 무시하면 프로세스 테이블이 좀비로 채워집니다.

+0

유닉스의 일부 맛보기에서는 SIGCHLD를 무시하면 자동으로 자식 프로세스를 거듭납니다 (분명히). http://www.faqs.org/faqs/unix-faq/faq/part3/section-13.html –

2

차단 또는 비 차단 모드에서 waitpid 기능을 사용하여 특정 자식의 신호를 기다린 다음 처리를 수행 할 수 있습니다. 실제로, 당신은 그레이엄의 답변에 명시된 바와 같이 어떤 종류의 wait을 사용하고있다 ...

3

당신은 신호를 잡으려고하고 기능을 호출합니다. 이 작업을 수행하려면 signal()을 사용하고 싶습니다 (man signal). 아래 예제에서 child_died()은 시그널 SIGCHLD가 포착 된 후에 호출됩니다 (이 시점에서 하위 프로세스가 작동하지 않습니다). child_died()에 조건부가 필요한 부모부터 자녀에게 전달해야하는 정보가 있으면 파이프 (man pipe)를 사용해야합니다.

#include <signal.h> 
#include <strings.h> 
#include <stdio.h> 

#define MAX_SIZE 256 

void child_died(int); 

int fd[2]; 

int main() 
{ 
    int pid; 
    extern int fd[]; 
    char *str; 

    pipe(fd); 
    signal(SIGCHLD, child_died); 

    if ((pid = fork()) < 0) { 
     // error 
     printf("Error\n"); 
    } else if (pid == 0) { 
     // child 
     printf("In child process\n"); 
     close(fd[0]); 
     str = strdup("Message from child process.\n"); 
     write(fd[1], str, strlen(str) + 1); 
    } else { 
     // parent 
     wait(); 
     printf("Now in parent\n"); 
    } 

    return 0; 
} 

void child_died(int s) 
{ 
    char *str; 
    close(fd[1]); 
    read(fd[0], str, MAX_SIZE); 
    printf("%s", str); 
} 

가 sigchld.c로 저장 컴파일 : 여기 신호 및 파이프의 예이다 gcc -Wall sigchld.c -o sigchld

하면 (하위 PID 등)를 int 또는 일부 다른 데이터 유형을 전달하려면 하위 프로세스를 부모 프로세스로 변환하려면 문자열로 변환 한 다음 다시 또는 다른 방법으로 찾아야합니다.

내 예제에서 SIGCHLD를 무시하려면 해당 논리를 child_died()에 넣으십시오. 그냥 if을 사용하면됩니다. 나는 당신이 신호를 무시할시기를 어떻게 결정하고 원하는 것을 인쇄 할 것인지를 모른다. 그래서 나는 위의 코드에 파이프를 포함시켰다. 하위 프로세스의 일부 정보를 사용하고 하위 프로세스에서 child_died()이 호출되었으므로 하위 프로세스에서 상위 프로세스로 데이터를 전송하는 방법이 필요합니다.

이 정보가 도움이되기를 바랍니다. 내가 잘 모르는 더 나은 방법이나 더 쉬운 방법이있을 수 있습니다. 그 때 코멘트가있는 경우에.

관련 문제