ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C/C++ wait(2), waitpid(2)
    C,C++ & Linux 2020. 6. 4. 00:34
    728x90

    함수 기능

    자식 프로세스의 종료 상태를 회수하는 함수입니다.

    부모 프로세스 입장에서는 자식 프로세스가 살아있는지 없는지 알 수 있는 방법이 없으므로 커널에서 시그널을 통해 부모 프로세스에게 알려줍니다. ( SIGCHLD 시그널 )

    함수 원형

    #include <wait.h>
    #include <sys/types.h>
    pid_t wait(int *statloc);
    pid_t waitpid(pid_t pid, int *statloc, int options);

     

    매개변수

    pid

    wait 할 프로세스의 아이디

    wait 의 경우 자식 프로세스 중 하나라도 종료된다면 리턴

    -1 을 지정하면 wait()와 waitpid(-1) 은 동일한 기능을합니다.

     

    statloc

    자식 프로세스의 종료 상태를 statloc에 담아줍니다.

     

    statloc 구조

     

    statloc 에 사용 가능한 매크로

    매크로 내용
    WIFEXITED(status) 자식 프로세스가 정상적으로 종료된 경우 true
    WEXITESTATUS(status) exit()의 인자에서 하위 8비트 값을 리턴
    WIFSIGNALED(status) 자식 프로세스가 시그널을 받아 비정상적으로 종료된 경우 true
    WIFTERMSIG(status) 시그널 번호를 리턴
    WIFCOREDUMP(status) 코어 파일이 생성된 경우 true
    WIFSTOPPED(status) 현재 중지 상태이면 true
    WSTOPSIG(status) 실행을 중단시킨 시그널 번호를 리턴
    WIFCONTINUED(status) 작업 제어 중지 이후 실행이 재개되었으면 true

     

    options

    Options 용도
    WCONTINUED 중지되었다가 실행을 재개한 이후 상태가 아직 보고되지 않은 자식도 리턴함
    WNOHANG 종료 상태를 즉시 회수 할 수 없는 상황이라고 하여도 waitpid() 호출이 차단되지 않고 0을 리턴함
    WUNTRACED 중지되었으나 그 상태가 아직 보고되지 않은 자식도 리턴함

    반환값

    성공 시 pid 리턴

    에러 시 -1 리턴

    waitpid의 경우 WNOHANG 옵션으로 실행되었고, 자식 프로세스가 종료되지 않았을 때는 0 리턴

    예제

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    
    #define EXIT_CODE 1
    
    int main() {
        pid_t pid;
        int ret_val, status;
    
        if ((pid = fork()) == 0) {
            printf("child: pid = %d ppid = %d exit_code = %d\n",
                    getpid(), getppid(), EXIT_CODE);
            exit(EXIT_CODE);
        }
    
        printf("parent: waiting for child = %d\n", pid);
        ret_val = wait(&status);
        printf("parent: return value = %d, ", ret_val);
        printf(" child's status = %x", status);
        printf(" and shifted = %x\n", (status >> 8));
        exit(0);
    }
    

     

    결과

    예제2

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    
    int main() {
        if (fork() == 0)
            execl("/bin/echo", "echo", "this is", "message one", (char *) 0);
    
        if (fork() == 0)
            execl("/bin/echo", "echo", "this is", "message two", (char *) 0);
    
        printf("parent: waiting for children\n");
    
        // 모든 자식이 종료되면 기다릴 자식이 없는데 wait 를 호출 한 것이므로 에러, -1을 리턴
        while (wait((int *) 0) != -1);
    
        printf("parent: all children terminated\n");
        exit(0);
    }
    

     

    결과

     

    예제3

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    
    int main() {
        pid_t child1, child2;
        int pid, status;
    
        if ((child1 = fork()) == 0)
            execlp("date", "date", (char *) 0);
    
        if ((child2 = fork()) == 0)
            execlp("who", "who", (char *) 0);
    
        printf("parent: waiting for children\n");
    
    	// 자식 프로세스가 종료되기를 기다림
        while ((pid = wait(&status)) != -1) {
            if (child1 == pid)
                printf("parent: first child: %d\n", (status >> 8));
            else
                printf("parent: second child: %d\n", (status >> 8));
        }
    
        printf("parent: all children terminated\n");
        exit(0);
    }
    

     

    결과

     

     

     

     

     

     

    리눅스시스템프로그래밍 저자 : 홍지만
    https://book.naver.com/bookdb/book_detail.nhn?bid=14623672

    책에 기술된 예제 프로그램입니다. 책 내부에는 훨씬 더 많은 자료가 있습니다. (개인적으로 좋았습니다.)

    댓글

Designed by Tistory.