[운영체제] fork() 함수란? , fork() 함수 예제 , 부모 자식 프로세스
fork() 함수란?
Unix 환경에서 fork() 함수는 함수를 호출한 프로세스를 복사하는 기능을 한다. 이때 부모 프로세스와 자식 프로세스가 나뉘어 실행되는데, 원래 진행되던 프로세스는 부모 프로세스(parent), 복사된 프로세스를 자식 프로세스(child) 라고 한다.
fork() 함수는 프로세스 id, 즉 pid 를 반환하게 되는데 이때 부모 프로세스에서는 자식 pid가 반환되고 자식 프로세스에서는 0이 반환된다. 만약 fork() 함수 실행이 실패하면 -1을 반환한다.
프로세스에 대해 잘 모르겠다면 다음을 참고하자.
fork() 함수는 COW(Copy On Write)를 사용하기 때문에 자식 프로세스와 부모 프로세스가 독립적으로 변수를 사용할 수 있다.
fork() 함수 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
pid_t pid;
int x = 1;
pid = fork();
if(pid == 0){ /*Child*/
printf("child: x=%d\n", ++x);
exit(0);
}
/*Parent*/
printf("parent: x=%d\n", --x);
exit(0);
}
|
cs |
위와 같은 코드를 실행하면 어떤 결과가 나올까? fork() 함수가 실행된 순간 프로세스가 하나 복사되고 이후 아래 코드들이 실행될 것이다.
위에서 자식 프로세스는 fork() 함수의 반환값이 0이라고 했다. 따라서 pid 가 0일 때는(child) x가 1증가해 "child: x=2" 가 출력된다.
반면 부모 프로세스는 pid가 자식의 프로세스 id를 가질 것이다. 따라서 "parent: x=0" 이 출력된다.
참고로 부모와 자식 프로세스 중 어떤것이 먼저 실행될지는 알 수 없다. 따라서
child: x=2
parent: x=0
순으로 출력될 수 도 있다.
몇가지 더 실험해보자.
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
printf("L0\n");
fork();
printf("L1\n");
fork();
printf("Bye\n");
}
|
cs |
위와 같은 코드는 어떻게 동작할까?? 그림으로 보면 간단하게 이해할 수 있다.
그림을 보면, fork() 를 할 때마다 자식 프로세스가 생기는 것을 확인 할 수 있다.
결과는 위와 같이 나올 수도 있고, 다른 결과가 나올 수도 있다.
어떤 프로세스가 먼저 실행될 지 알 수 없기 때문에, 위와 같은 순서대로 결과가 나오기도 한다.
이때 결과로 나올수 있는 것을 Feasible output, 결과로 나올수 없는 것을 Infeasible output이라고한다.
예를 들어 아래와 같다. 그림을 잘 보면서 이해해보자.
Feasible output Infeasible output
L0 L0
L1 Bye <- 불가능
Bye L1
Bye Bye
L1 L1
Bye Bye
Bye Bye
다음 예제도 봐보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
printf("L0\n");
if(fork() != 0){
printf("L1\n");
if(fork() != 0){
printf("L2\n");
}
}
printf("Bye\n");
}
|
cs |
역시 그림으로 이해해보자.
fork() 반환 결과가 0이라면 자식이고 0이 아니면(자식프로세스의 id를 가질것) 부모 프로세스이다. 따라서 if(fork() != 0)아래 코드는 부모 프로세스에서만 실행되는 것이다. 실행결과는 마찬가지로 다양한 결과가 나올 수 있다. 여기서도 Infeasible output을 생각해보면 좋을 것이다.
다음 예제도 봐보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
printf("L0\n");
if(fork() == 0){
printf("L1\n");
if(fork() == 0){
printf("L2\n");
}
}
printf("Bye\n");
}
|
cs |
역시 그림으로 이해해보자.
fork() 반환값이 0이라면 자식프로세스라는 것이다. 즉 if(fork()==0) 아래 코드는 자식프로세스에서만 실행되는 것이다!
마찬가지로 가능한 출력결과와 불가능한 출력결과를 생각해보자.