fork 함수로 자식 프로세스를 생성할 수 있다고 하였습니다. 그러면, 부모 프로세스가 자식 프로세스가 종료가 될 때 까지 대기를 하게 할 수 없을까요? 그럴 때 wait 함수를 쓰시면 됩니다.

 

 

pid_t wait(int *stat);

 

 

 성공 시에, 종료된 자식의 pid를, 실패하면 -1을 반환합니다. 물론 stat에 NULL값을 넣어도 되는데요. 이 때에는, 전달된 매개변수에 상태값을 저장하지 않습니다. man ps를 쳐 봅시다. 스크롤을 쭉 내리시면 아래와 같은 설명이 나오는데요.

 

 

 이는, 상태값에 따른 프로세스의 상태를 의미해요. 여기서 보아야 할 것은 R, 그러니까 run queue에 있는 상태. 이것과 S인데요. S는 interruptible sleep을 의미합니다. 인터럽트를 받을 수 있는 sleep? 인터럽트는 추후에 다시 언급을 하도록 하겠습니다.

 

 


 예제 프로그램 1을 봅시다.

 

 

 부모가 자식을 fork 함수로 생성하고 있어요. 그리고, pid가 0인 경우 자식이니까, 7번째 줄에 있는 if문 블록에 걸릴 거에요. 그런데 이 때, 자식은 무한 루프를 돌 겁니다. 한 번 실행을 시켜 볼까요?

 

 

 보시면 parent, 그러니까 fork를 호출한 프로세스의 pid가 3753이고, child는 3754였습니다.

 

 

 3754는 계속 R+, 그러니까 계속 돌고 있음을 알 수 있어요. 그리고 3753번은 S+인데요. 인터럽트를 받을 수 있는 sleep 상태임을 알 수 있어요. 그러면, wait 함수는 자식 프로세스가 종료될 때 까지 blocking 상태인가요? 네.

 

 

 이를 단순하게 도식화 시켜 보면 다음과 같습니다. 3753으로부터 생성된 child 3754가 계속 돌고 있습니다. 도는 동안 3753은 계속 block이 걸려 있다는 것을 알 수 있어요.

 

 


 그러면, child 1은 무한 루프를 돌게 하고, child 2는 바로 리턴하게끔 해 버리면 어떨까요? 아래 예제를 봅시다.

 

 

 보시면, 부모 프로세스에서 자식을 2개 생성하게 되어 있어요. 하나는 무한 루프를 돌고요.

 

 

 다른 하나는 3을 리턴해요. 이 프로그램을 실행 시켜 봅시다.

 

 

 그러면 parent가 4636이고, 자식이 4637과 4638임을 알 수 있어요.

 

 

 그런데 ps -au 명령어를 쳐 보면, 4636과 4638은 어디로 가고, 4637만 R상태임을 알 수 있어요. 이건 어떻게 된 일일까요? 중간 중간에 4638이 실행이 되어서, 종료가 되었고, 4636 입장에서는 child인 4638이 종료되었습니다. wait 함수는 임의의 자식이 종료될 때 까지 기다리는 함수인데요. 만약에 종료된 자식이 없다면, 계속 blocking 상태에 놓여 있을 겁니다.

 

 그런데 4638이 return 3을 수행해서 종료되었기 때문에, parent는 wait(NULL) 다음에 있는 return 0 문장을 수행할 수 있습니다. 따라서, 4637만 남아 있게 됩니다.

 

 


 그러면, parent가 child가 반환한 값을 얻어오게 할 수는 없을까요? wait에 int형 포인터 변수를 넘겨준다고 했는데요. 이것을 넘겨주면, stat에 상태값을 쓰게 됩니다.

 

 

 이 상태 값을 가지고, 매크로 함수를 호출할 수 있는데요. WIFEXITED는, 자식 프로세스가 정상적으로 종료한 경우 참 값을 반환합니다. 그런 경우, WEXITSTATUS로 리턴 값을 받아 올 수 있습니다. fork 함수로 프로세스를 생성하고, pid의 값이 0일 때, 그러니까 child process일 때, 3을 리턴했는데요.

 

 

 3을 받아왔음을 알 수 있어요.