C,C++ & Linux
C/C++ wait(2), waitpid(2)
KyooDong
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
책에 기술된 예제 프로그램입니다. 책 내부에는 훨씬 더 많은 자료가 있습니다. (개인적으로 좋았습니다.)