[Operating System] System Call


fork( ), exec( ), wait( )와 같은 것들은 Process 생성과 제어를 위한 System call임.


Fork

새로운 Process를 생성할 때 사용.그러나, 이상한 방식임.

#include <stdio.h> #include <stdlib.h> #include <unistd.h>int main(int argc, char *argv[]) { printf("pid : %d", (int) getpid()); // pid : 29146 int rc = fork(); // 주목 if (rc < 0) { exit(1); } // (1) fork 실패 else if (rc == 0) { // (2) child 인 경우 (fork 값이 0) printf("child (pid : %d)", (int) getpid()); } else { // (3) parent case printf("parent of %d (pid : %d)", rc, (int)getpid()); } }

pid : 29146parent of 29147 (pid : 29146)child (pid : 29147)

을 출력함 (parent와 child의 순서는 non-deterministic함. 즉, 확신할 수 없음. scheduler가 결정하는 일임.)

[해석]

PID : 프로세스 식별자. UNIX 시스템에서는 PID는 프로세스에게 명령을 할 때 사용함.

Fork()가 실행되는 순간. 프로세스가 하나 더 생기는데, 이 때 생긴 프로세스(Child)는 fork를 만든 프로세스(Parent)와 (almost) 동일한 복사본을 갖게 된다. 이 때 OS는 위와 똑같은 2개의 프로그램이 동작한다고 생각하고, fork()가 return될 차례라고 생각한다. 그 때문에 새로 생성된 Process (child)는 main에서 시작하지 않고, if 문부터 시작하게 된다.

그러나, 차이점이 있었다. 바로 child와 parent의 fork() 값이 다르다는 점이다. 따라서, 완전히 동일한 복사본이라 할 수 없다.

Parent의 fork()값 => child의 pid 값Child의 fork()값 => 0

Parent와 child의 fork 값이 다르다는 점은 매우 유용한 방식이다.

그러나! Scheduler가 부모를 먼저 수행할지 아닐지 확신할 수 없다. 따라서 아래와 같이 출력될 수 있다.

pid : 29146child (pid : 29147)parent of 29147 (pid : 29146)