불안정 상태의 프로세스(좀비 프로세스 등) 발생을 방지하기 위해서 부모와 자식 프로세스를 동기화 해야함
좀비 프로세스
실행 종료 후 자원 반납한 자식 프로세스의 종료 상태 정보를 부모 프로세스가 얻어가지 않는 경우에 발생함
- 정상적인 프로세스 종료 과정
- 자식 프로세스가 종료를 위해 부모 프로세스에 종료 상태 정보를 보냄
- 부모 프로세스는 이 정보를 받으면 프로세스 테이블에서 자식 프로세스 삭제
- 제거 방법
- 부모 프로세스가 wait 관련 함수를 호출해야 사라짐 (일반적인 방법으로는 제거 불가능)
- 고아 프로세스
- 자식보다 부모가 먼저 종료하면 자식은 고아 프로세스가 됨
- init(PID 1) 프로세스의 자식 프로세스로 등록됨
프로세스 동기화
부모 프로세스는 자식 프로세스가 종료될 때까지 기다려야 함
wait
자식 process가 종료할 때까지 부모 process를 기다리게 함
자식 process가 여러 개일 경우 아무 자식 프로세스나 종료하면 리턴함
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *stat_loc);
int main(){
int status;
pid_t pid;
pid = fork();
if(pid == 0){
//child Process
}
else if(pid >0){
while(wait(&status) != pid) continue;
printf("status: %d %x\n",status,status);
printf("child process exit status: %d\n",status>>8);
//오른쪽으로 8비트 이동해야 종료 상태값 알 수 있음
}
}
- stat_loc
- 상태 정보 저장할 주소
- 자식 process의 종료 상태는 stat_loc에서 지정한 주소에 저장됨
- NULL을 지정할 수도 있음
- 부모 process가 wait 함수를 호출하기 전에 자식 프로세스가 종료하면 wait은 즉시 리턴함
- wait 함수의 리턴값은 자식 프로세스의 ID
- 리턴값이 -1이면 살아있는 자식이 하나도 없다는 의미
waitpid
특정 자식 프로세스와 동기화
특정 PID의 자식 프로세스가 종료하기를 기다림
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *stat_loc, int options);
int main(){
int status;
pid_t pid;
pid = fork();
if(pid == 0){
//child process
}
while(waitpid(pid, &status,WNOHANG)==0){ //WNOHANG이라서 waitpid는 블락 안됨
printf("Parent still wait\n");
sleep(1);
}
printf("Child exit status : %d\n",status>>8);
}
- pid
- 종료 기다리는 PID
- -1보다 작을 경우 : pid의 절댓값과 같은 프로세스 그룹 ID 에 속한 자식 프로세스 중 아무거나 요청 (선착순)
- -1인 경우 : wait 함수처럼 임의의 자식 프로세스의 상태값 요청 (선착순)
- 0인 경우 : 함수 호출한 프로세스와 같은 프로세스 그룹에 속한 임의의 프로세스 상태값 요청
- 0보다 큰 경우 : 지정한 pid에 해당하는 프로세스 상태값 요청
- options
- waitpid 함수의 리턴 조건
- <sys/wait.h>에 정의됨, OR 연산으로 연결해서 지정 가능
- WCONTINUED : 수행 중인 자식 프로세스의 상태값 리턴됨
- WNOHANG : pid로 지정한 자식 프로세스의 상태값 즉시 리턴받을 수 없어도 이를 호출한 프로세스의 실행 블록하지 않고 다른 작업 수행하게 함
- 부모와 자식 동시에 수행 가능하게 함
- WNOWAIT : 상태값 리턴한 프로세스가 대기 상태로 머물 수 있게 함
- WUNTRACED : 실행 중단한 자식 프로세스의 상태값 리턴