공부/리눅스

fork() vfork() wait() waitpid()함수 예제

choryDev 2019. 10. 31. 11:20

학교에서 한 내용을 정리 한 것입니다.

 

fork()

fork()함수는 현재의 프로세스를 복제하여 자식 프로세스를 생성하는 함수입니다.

자식 프로세스를 생성한 현재의 프로세스를 부모 프로세스라고 합니다.

 

부모 프로세스 반환값: 자식 pid

자식 프로세스 반환값 :  0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "apue.h"                                                                                                                                                                  
                                                                                                                                                                                    
  int glob = 6;                                                                                                                                                                      
  char buf[] = "a write to stdout\n";                                                                                                                                                
                                                                                                                                                                                    
  int main(){                                                                                                                                                                        
         int var;                                                                                                                                                                       
         pid_t pid;                                                                                                                                                                     
                                                                                                                                                                                    
      var = 88;                                                                                                                                                                      
      if (write (STDOUT_FILENO, buf, sizeof(buf)-1 ) != sizeof(buf) -1)                                                                                                              
      ┆   err_sys("write err");                                                                                                                                                      
      printf("before fork\n");                                                                                                                                                       
                                                                                                                                                                                     
      if ((pid = fork()) < 0){                                                                                                                                                       
      ┆   err_sys("fork err");                                                                                                                                                       
      } else if (pid == 0){                                                                                                                                                          
      ┆   glob++;                                                                                                                                                                    
      ┆   var++;                                                                                                                                                                     
      } else {                                                                                                                                                                       
      ┆   sleep(2);                                                                                                                                                                  
      }                                                                                                                                                                              
                                                                                                                                                                                     
      printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);                                                                                                                
      exit(0);                                                                                                                                                                       
}
cs

 

vfork()

vfork()함수는 fork함수와 거의 같지만 exec함수를 실행 하기 전 까지는 부모와 자식이 같은 메모리를 참조 합니다.

 

부모 프로세스 반환값: 자식 pid

자식 프로세스 반환값 :  0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "apue.h"                                                                                                                                                                  
                                                                                                                                                                                    
  int glob = 6;                                                                                                                                                                      
                                                                                                                                                                                    
  int main(){                                                                                                                                                                        
       int var;                                                                                                                                                                       
       pid_t pid;                                                                                                                                                                     
                                                                                                                                                                                    
    var = 88;               
    printf("v포크 하기전\n");                                                                                                                                                       
    if((pid = vfork()) < 0){
        err_sys("vfork 에러");
    }else if(pid == 0){ //자식
      glob++;
      var++;
      exit(0);
    }
    //부모부분 계속
    printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);                                                                                                                
    exit(0);                                                                                                                                                                       
}
cs

wait()

wait함수는 자식 프로세스를 기다리는 함수이며, 자식 프로세스로 부터 signal을 받으면 커널로 종료됨을 알려 줍니다.

 

 종료된 자식이 에러 반환값 :  -1

 종료된 자식이 정상 반환값 : 0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <sys/types.h>
#include <sys/wait.h>
#include "apue.h"           
 
void pr_exit(int status)
{
    if(WIFEXITED(status))
        printf(" 정상 temination, exit status = %d|n",
                WEXITSTATUS(status));
    else if(WIFSIGNALED(status))
        printf("abnormal temination, signal number = %d\n",
                WTERMSIG(status));
    else if(WIFSTOPPED(status))
        printf("자식 멈춤, signal number = %d\n",
                WSTOPSIG(status));
}
 
int main(void){
 
    pid_t pid;
    int status;
 
    if((pid = fork()) < 0)
        printf("포크 에러");
    else if( pid == 0 )         //자식
        exit(7);
 
    if(wait(&status) != pid)   //자식을 위한 웨이트
        printf("웨이트 에러");
    pr_exit(status);            //상태 출력
 
    if((pid = fork()) < 0)
        printf("포크 에러");
    else if( pid == 0 )         //자식
        abort();                //SIGABRT 실핼
 
    if(wait(&status) != pid)   //자식을 위한 웨이트
        printf("웨이트 에러");
    pr_exit(status);            //상태 출력
 
    if((pid = fork()) < 0)      
        printf("포크 에러");
    else if( pid == 0 )         //자식
        status /=0;             //0나누기로 부터 SIGFPE
 
    if(wait(&status) != pid)   //자식을 위한 웨이트
        printf("웨이트 에러");
    pr_exit(status);            //상태 출력
 
}
cs


waitpid()

waitpid함수는 wait함수와 비슷하며 특정 프로세스를 종료되길 기다리는 함수이다.

 

반환

-1 > pid  :  그룹ID가 절대값과 같은 자식 프로세스를 기다립니다.

-1 == pid  :  아무 자식 프로세스 ID라도 기다립니다.

0 == pid  :  자신과 같은 프로세스 그룹ID를 가진 차일드 프로세스를 기다립니다.

0 < pid  :  넘겨진 pid인 자식 프로세스만 기다립니다.

0 < pid  :  넘겨진 pid인 자식 프로세스만 기다립니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "apue.h"
#include <sys/wait.h>
 
int main(){
    
    pid_t pid;
 
    if((pid = fork()) <0){
        err_sys("fork err");
    } else if(pid == 0){ //첫번쨰 자식
        if((pid = fork())< 0)
            err_sys("fork err");
        else if(pid > 0)
            exit(0); //두번째 자식의 부모 == 첫번째 자식
        sleep(2);
        printf("2nd child, parent pid = %d\n", getppid());
        exit(0);
    } 
    if (waitpid(pid, NULL0!= pid) //첫번째 자식 waitpid
        err_sys("waitpid err");
 
    exit(0);
}
cs