Skip to content

OSTEP 05 Process API

Published: at 오후 09:01

OSTEP 05 Process API

1. fork() 시스템 콜

OSTEP 05 Process API-1687712682168.jpeg

현재 실행중인 프로세스의 복사본을 생성한다. 운영체제가 새로운 프로세스를 생성하고 이 새로운 프로세스는 원본 프로세스의 메모리 공간을 복사하여 가지게 된다.

부모 프로세스에는 새로 생성된 자식 프로세스의 PID를 반환하고, 자식 프로세스에는 0을 반환한다. 반환값이 다르기 때문에 부모, 자식 프로세스가 서로 다른 작업을 하도록 코드를 짤 수 있다.

rc에 어떤 값이 리턴되었는지 확인하면, 현재 실행중인 프로세스가 부모 프로세스인지, 자식 프로세스인지 알 수 있다.

OSTEP 05 Process API-1687712698353.jpeg

CPU Scheduler가 실행할 프로세스를 선택하는데 이 때 자식 프로세스가 먼저 실행될 수 있다. 항상 부모 프로세스가 먼저 실행되는 것은 아니다.

2. wait() 시스템 콜

OSTEP 05 Process API-1687712816426.jpeg

부모 프로세스가 자식 프로세스가 종료될 때까지 기다리게 하는 시스템 콜. 이 함수를 호출하면 부모 프로세스는 자식 프로세스가 종료될 때까지 블록된다. 자식 프로세스가 종료되면 운영 체제는 부모 프로세스에게 제어를 반환하고. 자식 프로세스의 종료 상태를 부모 프로세스에게 전달한다.

OSTEP 05 Process API-1687712855061.jpeg

두 가지 case 모두 자식 프로세스가 먼저 출력한다.

  1. 부모 프로세스가 먼저 실행되는 경우 -> 바로 wait()을 호출. 이 시스템 콜은 자식 프로세스가 종료될 때까지 리턴하지 않는다. -> 자식 프로세스가 먼저 출력한다.
  2. 자식 프로세스가 먼저 실행되는 경우 -> 자식 프로세스가 먼저 출력한다.

3. exex() 시스템 콜

OSTEP 05 Process API-1687713059554.jpeg

현재 실행중인 프로세스의 메모리 공간을 새로운 프로그램으로 대체하는 시스템 콜. 이 함수를 호출하면 운영체제는 현재 프로세스의 메모리 공간을 세로운 프로그램으로 대체하고, 새로운 프로그램의 메인 함수를 실행한다. 자기 자신이 아닌 다른 프로그램을 실행해야 할 때 사용한다. exex() 함수가 성공하면 기존 프로그램은 리턴하지 않는다.

OSTEP 05 Process API-1687713142622.jpeg

execvp() 시스템 콜을 호출하면, 자식 프로세스의 메모리 공간이 새로운 프로그램인 wc로 대체되고, 원래 자식 프로세스는 리턴되지 않는다.

4. 왜 이런 API를?

UNIX의 쉘을 구현하기 위해서는 fork()exec()을 분리해야 한다. 그래야만 쉘이 fork() 를 호출하고 exec()를 호출하기 전에 코드를 실행할 수 있다.

쉘은 프롬프트를 표시하고 사용자가 무언가 입력하기를 기다린다. 그리고 명령어를 입력한다. 대부분의 쉘은 파일 시스템에서 실행 파일의 위치를 찾고 명령어를 실행하기 위하여 fork()를 호출하여 새로운 자식 프로세스를 만든다. 그런 후 exec()의 변형 중 하나를 호출하여 프로그램을 실행시킨 후 wait()을 호출하여 명령어가 끝나기를 기다린다. 자식 프로세스가 종료되면 쉘은 wait()으로부터 리턴하고 다시 프롬프트를 출력하고 다음 명령어를 기다린다.

OSTEP 05 Process API-1687713360756.jpeg

OSTEP 05 Process API-1687713373694.jpeg

p4를 실행하면 화면에 아무런 일도 일어나지 않는다. 그러나 실제로는 다음과 같은 일이 발생하였다.

  1. p4fork()를 호출하여 새로운 자식 프로세스를 생성한다.
  2. 그리고 wait() 호출 후 대기한다.
  3. 자식 프로세스는 출력을 재지정한다. (2번, 3번 어떤 일이 먼저 발생하는지 알 수 없음)
  4. execvp()를 호출하여 wc프로그램을 실행시킨다.

UNIX 파이프가 이와 유사한 방식으로 구현되지만, pipe() 시스템 콜을 통해 생성된다. 한 프로세스의 출력과 다른 프로세스의 입력이 동일한 파이프에 연결된다. 한 프로세스의 출력은 자연스럽게 다음 프로세스의 입력으로 사용되고, 명령어 체인으로 사용된다.

5. 기타 API

참고: OSTEP 교재