메뉴 건너뛰기


Developer > Application

C,C++ 좀비가 생기지 않는 fork()

2013.11.26 00:42

푸우 조회 수:19585

우선 좀비가 생기는 현상에 대해 알아보자.
 
자식 프로세스가 Execution 이  끝나면 OS Kernel 은 이 사실을 부모 프로세스에게  SIGCLD 또는 SIGCHLD 시그널을 보내 자식의 실행이 끝났다는 것을 알려주려하는데 부모 프로세스에서 이 시그널을 받아 처리 해주지 않으면 Defunct 로 zombie  프로세스가 된다.

이를 해결하기 위해서는  부모 프로세스는 fork() 하기전에 signal() 혹은 sigaction() 을  통해 SIGCLD 나 SIGCHLD 에 대한 handler 를 등록하고 SIGCHLD Signal 을 받을때  waitpid() 를 호출해서 자식 프로세스에 대한 cleanup 과정을 수행을 하고나서 return 을 통해서 다시 원래의 작업으로 돌아가야 한다.
예를 들면
 #include <errno.h> 
 #include <sys/wait.h>

int main() {
   signal(SIGCHLD, SigChild) ;

   if ((pid = fork()) < 0) {
       fprintf(stderr,"pid->%d fork error!!!\n",pid);
       exit (0);
   }
}
    
void SigChild(int signo) {
    pid_t pid ;
    int stat ;
   
     while ((pid = waitpid(-1, &stat, WNOHANG)) > 0)
          printf("child %d terminated normaly\n", pid) ;
      return ;
}

와 같이 해야 합니다.
 
만약 자식 프로세스가 끝나것에 관심이 없다면 다음과 같은 함수를 작성해서
fork() 대신에 다음 함수 fork2를 사용하면 된다.
 
int fork2()
{
    pid_t pid;
    int rc;
    int status;
    if (!(pid = fork()))
    {
        switch (fork())
        {
            case 0:  return 0;
            case -1: _exit(errno);    
            default: _exit(0);
        }
    }
    if (pid < 0 || waitpid(pid,&status,0) < 0)
        return -1;
    if (WIFEXITED(status))
        if (WEXITSTATUS(status) == 0)
            return 1;
        else
            errno = WEXITSTATUS(status);
    else
        errno = EINTR; 
    return -1;
}


Creative Commons License
Creative Commons License이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
Copyright 조희창(Nicholas Jo). Some rights reserved. http://bbs.nicklib.com