시그널 처리 질문

dotri의 이미지

자식 프로세스가 죽을때 장례치러주는 코드입니다.

void SigHandler( int signo )
{
    int n;
    waitpid( -1, &n, 0 );
    return;
}

int main( void )
{
    struct sigaction act;
    act.sa_handler = SigHandler;
    act.sa_flags = 0;
    sigemptyset( &act.sa_mask );
    sigaction( SIGCHLD, &act, NULL );

    while( 1 )
    {
        int PID;

        if( 어떤 이벤트 발생시 )
        {
            PID = fork();
            if( PID == 0 )
            {
                SomeTask();
                exit( 0 );
            } else
                continue;
        } // if
    } // while

    return 0;
}

이때 if() 문의 조건이 되는 이벤트는 상당히 자주 발생하여, 어떨때는 자식 프로세스가 1000개가 넘개 생성될수도 있습니다. 자식중 하나가 죽으면, 부모가 SIGCHLD 를 받게 되므로, 그때 자식을 장례치러주면 될것 같아서 이렇게 코드를 작성했습니다.

그런데, 이 프로그램을 돌려보니, 생성되는 자식 프로세스 100개당 1개 비율로 자식이 좀비가 되버리더군요. 어떤 처리를 더 해주어야 좀비가 생기지 않는것을 보장받을 수 있나요?

hb_kim의 이미지

유닉스 시스템에서 시그널은 대부분 비트로 표현되고 여러 인스턴스가 큐잉이 되지 않으므로, 시그널 핸들러가 처리하기전에 여러개의 시그널 인스턴스가 입력되면 그중 하나만 처리하게 됩니다.

따라서 시그널 핸들러에서 waitpid 를 반복해서 호출해줘야 됩니다.

void SigHandler( int signo )
{
    pid_t pid;
    while ((pid = waitpid(-1, 0, WNOHANG)) > 0);
    return;
}