내장형 하드웨어/TCP/IP

TCP/IP - fork_test.c, 좀비 프로세스

동화다아아 2011. 7. 14. 17:53

// fork_test.c 
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>

int global_val = 0// 전역 변수 선언

int main()
{
        pid_t fork_ret, child;
        
int local_val = 0// 지역 변수 선언

        
fork_ret = fork();
        
if(fork_ret<0)
        {
                printf(
"fork() error \n");
                exit(
1);
        }
        
else if(fork_ret == 0// 자식 프로세스인 경 경우         

        {
                global_val++;
                local_val++;
                printf(
"CHILD - my PID : %d  parents's PID : %d\n",

                                                                 getpid() ,getppid());
        }
        
else // 부모 프로세스인 경 경우 

        {
                sleep(
10); // 테스트 위한 10초 대기
                
global_val = global_val + 5;
                local_val 
= local_val + 5;
                printf(
"PARENT - my PID : %d  child's PID : %d\n"

                                                                getpid(), fork_ret);
        }
        printf(
"\t global_val : %d\n", global_val);
        printf(
"\t local_val  : %d\n", local_val);
        
return 0;


}

⇒ 출력 결과         

 

⇒ 출력 결과(sleep(10)을 주지 않았을 때)         

       

 → 빨간 칸 안에 parents's PID  값이 1인 이유는 CHILD에서 PARENT를 불러오는 시점에 이미 PARENT 프로세서가 죽어버렸기 때문이다.

⇒ 좀비 프로세스 확인

 

⇒ 위의 PID 번호를 확인하면 좀비프로세스와 child's PID 번호가 일치함을 알 수 있다.




- 좀비 프로세스

⇒ 프로세스 종료 후 메모리상에서 사라지지 않은 프로세스


⇒ 좀비 프로세스 생성 이유

 → 자식 프로세스가 종료하면서 반환된 값 0을 커널이 부모 프로세스에 전달한 후 자식 프로세스를 소멸시킴.

 → 반환값을 부모 프로세스에 전달하지 못한 경우 자식 프로세스는 좀비로 존재.

 → 부모 프로세스가 커널에게 종료된 자식 프로세스의 리턴값을 전달 요청을 해야만 커널이 리턴값 전달 가능함



1. wait 함수

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int * status);

공시 종료된 자식 프로세스 ID, 실패시 -1 리


 → status : 포인터 status가 가리키는 변수에 자식 프로세스 종료시 리턴하거나 exit 함수 호출시 전달한 인자값이 저장됨

 → 매크로함수 WEXITSTATUS(status)로 종료시 리턴값이나 exit() 인자로 넘겨진 값 확인

 → 호출 시점에 종료된 자식 프로세스가 없으면 blocking 상태에 빠짐


2. waitpid 함(wait함수의 blocking 상태 해결)

#include <sys/types.h>

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int * status, int options);

공시 종료된 자식 프로세스ID(경우에 따라 0), 실패시 -1 리턴


 → pid : 종료 확인을 원하는 자식 프로세스 ID. 임의의 자식 프로세스인 경우 -1 대입.

 → status : wait 함수의 status와 같은 역할

 → options : sys/wait.h에 정의된 ‘WNOHANG’ 상수를 인자로 전달하게 되면 이미 종료한자식 프로세스가 없는 경우 blocking 상태로 가지 않고 바로 리턴함.  이때 waitpid 함수의 리턴값은 0이 된다.


 

#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>

int global_val = 0;

int main()
{
        pid_t pid, child;
        
int local_val = 0;
        
int state;
        pid 
= fork();
        
if(pid < 0)
        {
                printf(
"fork() error");
                exit(
1);
        }
        
else if(pid == 0// 자식 프로세스인 경 경우     

        {
                global_val++;
                local_val++;
                printf(
" CHILD = my PID :%d   parent's PID : %d\n"

                                                                getpid(), getppid());
        }
        
else // 부모 프로세스인 경 경우 

        {
                global_val 
= global_val + 5;
                local_val 
= local_val + 5;
                printf(
"PARENT = my PID : %d  child's PID : %d\n", getpid(), pid);

                child 
= wait(&state); // 자식 프로세스의 종료 대기
                
printf("\t Child PID = %d\n", child);
                printf(
"\t return value = %d\n", WEXITSTATUS(state));

                sleep(
10); // 좀비 프로세스 있는지 확인할 시간벌기 위한 대기
        }
        printf(
"\t global_val : %d\n", global_val);
        printf(
"\t local_val  : %d\n", local_val);
  

        return 0;
}

⇒ 출력 결과         

 

⇒ 출력 결과 (./fork_wait → ps -u)         

 

 → 좀비 프로세스가 없어진 것을 확인 할 수 있다.