fork - exec / wait +clone
fork
1
2
3
#include <unistd.h>
pid\_t fork(void);
fd
child는 parent의 file table을 복사해가기 때문에
fork()
나 exec()
나 fd
는 유지된다. * thread는 main thread의 context를 공유하기 때문에, thread도 마찬가지다.
exec
2017/03/08 - [System/etc] - exec 계열 함수
wait (man wait )
All of these system calls areused to wait for state changes in a child of the calling process, and obtain information about the child whose state has changed. A state change is considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal. In the case of a terminated child, performing a wait allows the system to release the resources associated with the child;if a wait is not performed, then the terminated child remains in a “zombie” state (see NOTES below).
자식은 부모가 종료를 받아주어야만 종료할 수 있다. 부모가 wait를 호출하지 않아 종료를 받아주지 않는다면, 자식은 부모가 종료될 때 까지 defunct
상태가 된다. 부모가 종료되고 나면 고아가 된 자식을 init이 데려가 종료를 받아주어 자식이 종료된다. 즉, 좀비 프로세스는 부모 프로세스가 wait를 호출하지 않고, 아직 종료되지 않은 상태에서 자식이 먼저 종료할 경우 발생한다. 부모 프로세스가 먼저 종료하는건 문제가 되지 않는다. 고아 프로세스는 init이 데려가게 되니까.
e.g.
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
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char \*\*argv){
pid\_t pid;
switch (pid = fork()) {
case -1 :
perror("fork");
exit(1);
break;
case 0 :
printf("child pid %d\n", getpid());
execlp("ls", "ls", "-a", (char \*)NULL);
printf("this may not printed - child \n");
break;
default :
//wait(0);
printf("parent inside switch - parent\n");
sleep(999);
break;
}
printf("outside switch %d\n", getpid());
return 0;
}
wait 하지 않을 경우 :
부모가 wait하지 않았고 sleep()으로 대기하고 있는 상태다. 이 같은 상황에서 child process는 좀비 프로세스가 된다.
wait 하는 경우 :
wait로 자식 프로세스의 실행이 끝날 때 까지 대기하다 (ls 출력) 자식프로세스 종료를 받아주고 나서 parent inside… 문구가 출력되고 sleep하였다.
clone
부모와 메모리를 공유하기 때문에, fork()
보다는 스레드에 가깝다.