대부분의 시스템에서 프로세스들은 병행 실행되면서 동적으로 생성되고 제거되야 한다.
때문에 OS는 프로세스 생성 및 종료를 위한 기능을 제공해야한다. 이번 페이지에서는 프로세스 생성 방법에 대해 살펴보도록 하겠다 .
1. 프로세스 생성
프로세스가 실행되는 동안 하나의 프로세스는 여러 개의 새로운 프로세스들을 생성할 수 있다.
이때, 프로세스를 생성한 프로세스
를 부모 프로세스
라고 하고 생성된 프로세스
를 자식 프로세스
라고 한다.
마찬가지로 자식 프로세스들도 프로세스를 생성할 수 있다. 이 결과들을 그림으로 표현하면 하나의 트리
가 완성된다.
대부분의 현대 OS들은 프로세스 식별자(pid)
를 사용해서 프로세스를 구분한다. 당연히 pid는 시스템의 각 프로세스에 고유한 값을 가지도록 할당된다. 이 식별자는 프로세스의 다양한 속성에 접근하기 위한 index
로 활용된다.
- Linux의 전형적인 프로세스 트리
언제나 pid = 1인 systemd 프로세스
가 모든 사용자 프로세스의 root 부모 프로세스 역할을 수행 & 부팅될 때 생성되는 첫 번째 사용자 프로세스다. 시스템이 부팅되면 systemd 프로세스
는 다양한 사용자 프로세스를 생성한다.
현재 활성화 되어 있는 프로세스를 재귀적으로 추적하면 위 그림과 같은 트리를 얻을 수 있다.
일반적으로 프로세스가 자식 프로세스를 생성
할 때 그 자식 프로세스
는 작업을 수행하기 위한 자원(CPU 시간, 메모리, 파일, 입출력 장치)이 필요하다. 이 자원들을 OS로부터 얻거나 부모 프로세스가 가진 자원의 부분 집합만을 사용하도록 제한될 수 있다.
이렇게 제한함으로써 자식 프로세스들이 많이 생성되어서 시스템 과부하 상태를 예방할 수 있다.
부모 프로세스
는
- 자원을 분할해서 자식 프로세스들에게 나누어 주거나
- 메모리나 파일과 같은 몇몇 자원들은 자식 프로세스들이 공유해서 사용하게 할 수 있다
- 뿐만 아니라 자식 프로세스에게 초기화 데이터(입력)를 전달할 수 있다.
프로세스가 새로운 프로세스를 생성할 때 2개의 프로세스를 실행시킬 수 있는 2가지 방법이 존재한다.
- 부모는 자식과 병행하게 실행을 계속한다.
- 부모는 일부 또는 모든 자식이 실행을 종료할 때까지 기다린다.
그렇다면, 자식 프로세스를 주소 공간을 기준으로 볼 때 2가지를 얘기할 수 있다.
- 자식 프로세스는 부모 프로세스의 복사본이다. (즉, 자식 프로세스와 부모 프로세스가 똑같은 프로그램과 데이터를 갖는다)
- 자식 프로세스가 자신에게 load될 새로운 프로그램을 갖고 있다.
ex) UNIX 운영체제
- 각 프로세스는 프로세스 식별자로 확인된다. 이는 유일한 정수값이다.
- 새로운 프로세스는 fork() 시스템 콜로 생성된다.
- 이때, 새로운 프로세스는 원래 프로세스의 주소 공간의 복사본으로 구성된다.
- 이 방법을 통해 부모 프로세스는 쉽게 자식 프로세스와 통신할 수 있다.
- 부모와 자식 프로세스는 fork() 이후의 명령어에서부터 실행을 계속한다.
- 다만, 자식 프로세스의 식별자는 부모 프로세스의 식별자로 반환되고
- 새로운 프로세스는 '0'이 반환된다.
fork() 실행 이후에 두 프로세스 중 하나의 프로세스가 exec() 시스템 콜
을 사용해서 자신의 메모리 공간을 새로운 프로그램으로 교체한다. exec() 시스템 콜
은 이진 파일(binary file)을 메모리로 적재(load)하고 그 프로그램을 실행한다.
이와 같은 방법으로 두 프로세스는 서로 통신할 수 있고 각자 원하는대로 작업을 실행한다.
부모 프로세스
는 더 많은 자식 프로세스를 생성할 수 있고 자식 프로세스가 실행되는 동안 별다른 작업이 없다면
자식 프로세스가 다 종료될 때 까지 ready queue
에서 자신을 제거하기 위해 wait() 시스템 콜
을 한다.
- 앞서 설명한 Unix 시스템 콜
1) fork()를 통해 동일한 프로그램의 복사본을 실행하는 2개의 서로 다른 프로세스를 갖는다.
- 자식 프로세스에게 보이는 pid 값은 0
- 부모 프로세스의 pid값은 0보다 큰 정수 값이다.
- 자식 프로세스는 특권(privileges)과 스케쥴링 속성을 모두 부모 프로세스로부터 상속받는다.
2) 자식 프로세스는 execlp() 시스템 콜을 사용해서 자신의 주소 공간을 /bin/ls의 출력 결과로 덮어 쓴다.
3) 부모 프로세스는 wait() 시스템 콜로 자식 프로세스가 끝나기를 기다린다.
- 자식 프로세스가 끝나면 부모 프로세스는 wait() 호출로부터 재개해서 exit() 시스템 콜을 사용하면서 끝난다.
2. 프로세스 종료
p.134 / p.159
'OS Concepts 10th' 카테고리의 다른 글
[OS] 3-2. 프로세스 스케쥴링 (0) | 2023.09.05 |
---|---|
[OS] 3-1. 프로세스 개념 (0) | 2023.09.04 |
[OS] Chapter 3. Process (0) | 2023.09.03 |
[OS] 2-8. OS 구조 (0) | 2023.09.02 |
[OS] 2-5. 링커와 로더(Linker and Loader) (0) | 2023.09.02 |