5장. 프로세스의 생성과 소멸
1. 프로세스의 이해
- 오늘날의 운영체제: '멀티 프로세스 운영체제'
프로세스란 무엇인가?
- 예를 들어서, 하드디스크에 저장된 게임의 실행파일 이름이 block.exe라고 한다면 이것은 보통 프로그램이라고 한다. 이 게임의 실행파일인 block.exe를 더블 클릭하면 실행을 위해 메모리 할당이 이뤄지고, 그 메모리 공간에 바이너리 코드가 올라가게 된다. 이 순간부터 프로세스라고 한다.
- 즉, 프로세스는 실행 중에 있는 프로그램을 의미한다.
프로세스를 구성하는 요소
-
Execution of C Program
프로세스 생성 시 만들어지는 메모리 구조
[Code 영역] 실행 파일을 구성하는 명령어들이 올라가는 메모리 영역
[Data 영역] 전역변수나 static 변수의 할당을 위해 존재하는 메모리 영역
[Heap 영역] 동적 할당을 위해 존재하는 메모리 영역
[Stack 영역] 지역 변수 할당과 함수 호출 시 전달되는 인자 값들의 저장을 위한 메모리 영역
→ 위 메모리 구조는 이 자체로 프로세스라고 표현하기도 한다. 왜냐하면 프로그램 실행을 위해서 명령어들이 메모리 공간에 올라와 있는 상태이고, 프로그램 실행을 위해 필요한 메모리 공간이 할당되어 있는 상태이기 때문이다.
-
Register Set
- 프로그램 실행을 위해서 CPU 내에 레지스터들이 절대적으로 필요하다.
- CPU 내에 존재하는 레지스터들은 현재 실행 중인 프로그램을 위한 데이터들로 채워진다.
- 레지스터들의 상태까지도 프로세스의 일부로 포함시켜서 말할 수 있다.
2. 프로세스의 스케줄링과 상태 변화
"CPU는 하나인데, 어떻게 여러 개의 프로그램이 동시에 실행 가능한가?"
- CPU는 한 순간에 하나의 프로그램만 실행 가능하다.
프로세스의 스케줄링
- 위 질문에 대한 방법으로 프로세스 스케줄링이 있다.
- 하나의 CPU가 여러 개의 프로세스를 번갈아 가면서 실행하는 것
- CPU는 아주 빠르기 때문에 하나의 CPU가 여러 프로세스를 고속으로 번갈아 가며 실행시킬 경우, 프로그램 사용자들은 CPU가 동시에 여러 개의 프로그램을 실행시킨다고 느끼게 된다. 결국 우리가 사용하는 멀티 프로세스 운영체제에서 여러 개의 프로세스가 실행되는 것처럼 보이는 이유는 여러 개의 프로세스들이 CPU 할당 시간을 나누기 때문이다.
스케줄링의 기본 원리
- 스케줄링(Scheduling): 프로세스의 CPU 할당 순서 및 방법을 결정짓는 일
- 스케줄링 알고리즘(Scheduling Algorithms): 스케줄링에 사용되는 알고리즘
- 스케줄러(Scheduler): 스케줄링 알고리즘을 적용해서 실제 프로세스를 관리하는 운영체제 요소(모듈)
멀티 프로세스는 CPU를 바쁘게 한다.
- 우리가 실행해야 할 프로세스 A, B, C가 있다고 가정하자.
- 고전적인 방식의 프로세스 실행
- 각 프로세스를 실행하고, 완전히 종료된 시점에서 다음 프로세스 실행을 반복
- 동시에 프로세스 실행
- A, B, C 프로세스를 모두 실행시킨 후 멀티 프로세스 운영체제의 스케줄러에 의해 프로세스들이 관리되도록 함. 즉 정해진 순서에 의해 CPU의 실행시간을 나눠서 할당받아 실행하는 형태
- 일반적으로 프로그램이 실행되는 과정에서 많은 시간을 I/O에 할당한다.
프로세스의 상태 변화
- 멀티 프로세스 운영체제에서는 프로세스 하나가 계속해서 실행되는 것이 아니고, 여러 개의 프로세스들이 돌아가면서 실행되기 때문에, 프로세스 각각의 상태는 시간의 흐름에 따라 변화한다.
- 상황 1: S(start)에서 Ready 상태로의 전이
- S는 프로세스 생성을 의미
- 프로세스는 생성과 동시에 Ready 상태로 들어간다.
- Ready 상태에 있는 프로세스는 CPU에 의해서 실행되기를 희망하는 상태
- 멀티 프로세스 운영체제이기 때문에 스케줄러에 의해 CPU에서 실행되기를 기다려야 함
- 상황2: Ready 상태에서 Running 상태로의 전이
- Ready 상태의 프로세스들은 스케줄러에 의해 관리되는 프로세스들이다.
- Ready 상태에 있는 프로세스 중 스케줄링 알고리즘에 기반을 둔 스케줄러에 의해 선택된 프로세스는 Running 상태가 되어 실행된다.
- 상황3: Running 상태에서 Ready 상태로의 전이
- 일의 중요도에 따라 실행 순서를 달리하기 위해 프로세스에는 우선순위라는 개념이 존재
- 즉 프로세스들은 생성 시 중요도에 따라 우선순위가 매겨진다.
- 우선 순위가 높은 프로세스가 실행 중일 경우, 우선 순위가 낮은 프로세스는 실행되지 않는다.
- 현재 우선 순위가 낮은 프로세스가 실행중이라면, 우선 순위가 높은 프로세스가 실행될 경우, 우선순위가 낮은 프로세스는 Ready 상태로 들어가고 우선순위가 높은 프로세스가 실행된다.
- 자신보다 중요한 우선 순위가 높은 프로세스가 있다면 어쩔 수 없이 양보하여, Ready 상태로 들어가고 이 상태에 존재하는 프로세스는 상황에 따라서 언제든지 다시 실행될 수 있다. 즉, 스케줄러의 관심 대상이다.
- 상황 4: Running 상태에서 Blocked 상태로의 전이
- 실행 중에 있는 프로세스가 실행을 멈추는 상태로 들어가는 것
- 일반적으로 데이터 입/출력에 관련된 일을 하는 경우에 발생
- 예를 들어 실행중인 프로세스 A가 파일 출력을 해야만 하는 상황이라면, Blocked 상태가 되어 파일 출력을 진행하는다. 이 때 프로세스 A가 Blocked 상태로 들어감과 동시에 Ready 상태에 있는 프로세스 중 하나가 Running 상태가 된다.
- 입/출력에 관한 프로세스는 CPU 연산을 필요로 하지 않으므로, 다른 프로세스에게 CPU를 양보하고 Blocked 상태로 들어간다. Running 상태에서 Ready 상태로 가지 않는 이유는 입/출력에 관한 작업이 끝나지 않았는데 스케줄러에 의해 선택된다면 현명하지 않은 선택이 될 수 있으므로, 스케줄러에 의해 선택되지 않도록 Blocked 상태로 가는게 현명하다.
- 상황 5: Blocked 상태에서 Ready 상태로의 전이
- Blocked 상태는 스케줄러에 의해 선택될 수 없는 상태를 의미한다. 이는 Ready 상태와의 가장 큰 차이점이다.
- Ready 상태는 스케줄러에 의해 선택되어 당장이라도 실행 가능한 상태
- Blocked 상태는 스케줄러에 의해 선택될 수 없는 상태
- 앞서 예시를 들었던 파일 출력을 해야하는 프로세스 A가 Blocked 상태가 되었지만, 파일 출력이 완료된 프로세스 A는 다시 Ready 상태가 되어 스케줄러에 의해 선택되길 기다려야 함
3. 컨텍스트 스위칭
"CPU 내에 존재하는 레지스터들은 현재 실행 중에 있는 프로세스 관련 데이터들로 채워진다."
- 현재 CPU에서 Running 상태에 있는 프로세스를 A라고 한다면, CPU의 레지스테에 프로세스 A와 관련된 데이터들이 존재한다.
- 이 때, Ready 상태의 프로세스 B는 프로세스 A를 실행하기 위해 기존 CPU의 레지스터에 저장된 데이터들을 메모리에 백업되어 있다.
- 이제 프로세스 B를 실행하기 위해서 프로세스 B와 관련된 레지스터 정보가 임시적으로 메모리에 백업되어 있었는데, 프로세스 B가 Running 상태가 될 경우 이를 다시 레지스터로 채워야 한다.
- 그리고 Ready 상태로 들어갈 프로세스 A는 현재 진행중이던 레지스터의 데이터들을 임시적으로 메모리에 백업해야 한다.
→ 이 과정을 '컨택스트 스위칭'이라고 한다.
멀티 프로세싱의 단점
"실행되는 프로세스의 변경과정에서 발생하는 컨텍스트 스위칭은 시스템에 많은 부담을 준다."
- 이는 레지스터 개수가 많을수록, 프로세스별로 관리되어야 할 데이터 종류가 많을수록 더하다.
→ 시스템을 디자인하는데 있어서, 이러한 컨텍스트 스위칭 부담을 최소화 하기 위해 많은 노력이 필요함
4. 프로세스의 생성
CreateProcess 함수의 이해
BOOL CreateProcess (
LPCTSTR IpAPPlicationName,
LPTSTR IpCommandLine,
LPCECURITY_ATTRIBUTES IpProcessAttributes,
LPSECURITY_ATTRIBUTES IpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID IpEnvironment,
LPCTSTR IpCurrentDirectory,
LPSTARTUPINFO IpStartupInfo,
LPPROCESS_INFORMATION IpProcessInformation
);
- LPCTSTR IpAPPlicationName: 생성할 프로세스의 실행파일 이름을 인자로 전달한다.
- LPTSTR IpCommandLine: 생성하는 프로세스의 인자를 전달할 때, 이 매개변수를 사용
CreateProcess 함수를 생성하기 위한 전체적인 구조
CreateProcess 함수를 호출하기 위해서 2개의 구조체를 선언해야 한다.
-
LPSTARTUPINFO
- 생성하고자 원하는 프로세스 특성 정보를 설정하면서 인자로 전달
- CreateProcess 함수는 인자로 전달한 정보를 참조해서 요구사항에 맞게 프로세스를 생성
- 정보를 전달하기 위한 구조체
-
LPPROCESS_INFORMATION
- 생성된 프로세스 정보를 반환하기 위한 구조체
- CreateProcess 함수를 호출할 때, 이 구조체를 먼저 선언해서 LPSTARTUPINFO 구조체와 함께 동시에 전달한다.
- CreateProcess 함수는 생성된 프로세스 정보를 LPPROCESS_INFORMATION 구조체에 채워준다.
- 정보를 얻기 위한 구조체
Process A(부모 프로세스) — CreateProcess에 의한 생성 —> Process B(자식 프로세스)
- CreateProcess 함수를 호출하는 프로세스를 부모 프로세스 (Parent Process)라고 한다.
- CreateProcess 함수 호출에 의해 생성된 프로세스를 가리켜 자식 프로세스 (Child Process)라고 한다.
- 생성하는 프로세스와 생성되는 프로세스 간에 부모-자식 간의 관계가 형성됨
Reference