오늘은 sleep sort에 나왔었던, unistd.h에 있는, 리눅스 fork 함수에 대해서 알아보겠습니다.

 

 

int fork();

 

 

 이것만 보면 별 거 없어요. 그냥 프로세스를 생성해주는 역할을 합니다. 그런데, 리턴 값이 2개인데요.

 

 

 예를 들어서 process A에서 fork가 호출되어서 process B가 생성이 되었다고 합시다. 그러면, A의 자식은 B가, B의 부모는 A가 됩니다.

 

 

 그러면, 이 때, 프로세스 B에서는 0이라는 값이, 프로세스 A에는 B의 pid 값이 리턴이 됩니다.

 

 


 이제 이 함수를 호출하면 어떤 식으로 흘러가는지 예제만 보도록 하겠습니다.

 

 

 먼저 global 변수와, heap, stack 변수를 하나씩 생성했습니다. 그리고 10번째 줄에서 문제의 함수를 호출하였습니다. 일단, 그러면 부모던 자식이던, fork 함수의 리턴 값을 res에 넣는 흐름까지 실행이 될 거에요.

 

 

 그러면 이런 상태에요. 그러면 res가 0일 때와 아닐 때가 실행 흐름이 나뉠 거에요.

 

 

 그러면 그 흐름을 따라가 봅시다. 일단 parent인 경우 wait(0);이 떡하니 있습니다. 이는 임의의 자식 프로세스가 하나 종료되기를 기다리는데요. 종료될 때 까지 block이 됩니다. 즉, 자식 부분이 먼저 실행이 될 거에요. 일단 복사 되기 전에, 메모리 구조는 다음과 같을 거에요.

 

 

 그런가요? 만약에 process A와 process B가 저 메모리 공간들을 share 해서 쓴다면, 프로그램이 끝나기 직전에 부모 프로세스가 출력하는 값은 1+2 = 3일 겁니다.

 

 

 그런데 실제 출력 값은, 자식이 종료되기 직전에 2 2 2가, 부모가 끝나기 직전에 1 1 1이 출력이 되었습니다. 이는 fork가 호출이 되면, 스택, 힙, 데이터 영역과 같은 것을 share 하지 않는다는 이야기입니다. 즉, 이 함수로 프로세스를 생성하면, 메모리 공간은 copy가 된다는 겁니다.

 

 

 이렇게요. 그러면, A에서의 global하고 B에서의 global은 아예 다른 공간을 가리키겠네요.

 

 먼저 자식 프로세스가 global, heap[0], stack 변수에 2를 증가시킵니다. 그러면 요래 될 거에요. 당연하게도 printf문으로 출력을 해 보면 각각 2, 2, 2가 나올 겁니다.

 

 

 자식 프로세스가 종료되면 wait(0) 다음에 있는 문장들이 수행이 되는데, 이것들은 각각 1씩 증가시켜주는 역할을 합니다. 자식 프로세스의 메모리 공간과는 별개이기 때문에, printf문으로 출력하면 3 3 3이 아닌 1 1 1이 출력이 됩니다.