Process
Process 는 실행 중인 프로그램이다. 실제 우리는 운영체제에서 여러개의 프로그램을 동시에 실행시키는 데 이는 어떻게 가능한 것인가?
CPU를 Virtualize(가상화) 하여서 CPU가 여러개 인 것 처럼 생각하게 한다. 가상화 기법으로 CPU는 Time Sharing(시분할, 흔히 사용됨), Space Sharing(공간분할)을 사용한다.
- Time Sharing: 일정 시간 마다 Process가 CPU 자원을 점유
- Space Sharing: 디스크처럼 공간을 분리해 특정 부분만 점유
Concept
위에서 말했듯이 Process는 실행중인 프로그램이다. 명령어와 정적 데이터로 디스크에 존재하나 이 자체로는 의미를 갖지 않으며 운영체제가 이에 생명을 불어넣어준다.
구성 요소
- memory : 실행되는 process는 memory에서 읽고 쓰여진다. 매우 중요한 요소
- register: 하드웨어 상태 기록을 위해 register(레지스터)에 기록된다.
- 어느 명령어를 실행 중인지 알려주는 register: PC(Program Counter) 혹은 IP(Instruction Pointer)
- 함수 변수, 리턴 주소 기록 register: SP(Stack Pointer), FP(Frame Pointer)
Process API 구성
간단한 Process API 역할을 기록합니다.
- Create : Process 생성
- Destroy : Process 강제 종료
- Wait : Process 대기
- Miscellaneous Control : 다양한 제어. e.g. Process 일시정지, 다시 시작
- Status : Process 상태 정보. 얼마나 사용되었는 지, 어떤 상태인지.
Process 생성 과정
- 운영체제는 Process 생성을 위해 디스크에서 프로그램, 정적 파일을 Load 하여 메모리에 저장한다.
- 프로그램 시작 전 run-time 용으로 Stack이 할당되어야하고, Heap 메모리를 할당한다.
- 입출력 File Descriptor인 STDIN, STDOUT, STDERROR 를 초기화한다.
위 3단계를 거쳐서 Process가 생성되어 main()함수에서 분기하여 시작된다.
최근 현대 운영체제에서는 Paging 과 Swapping 을 통해 필수적인 데이터만 메모리에 Load한다.
Process 상태
- Running(실행): Process 실행 중
- Ready(준비): Process 실행할 준비가 되었지만 운영체제가 다른 Process 실행과 같은 이유로 실행 안시키고 있는 것.
- Blocked(대기): Process가 다른 작업 기다리는 동안 수행을 중단 시키는 것. e.g. 파일 입출력
1. 프로세스 상태 추이: CPU만 이용할 때
| 시간 | Process0 | Process1 | 비고 |
|---|---|---|---|
| 1 | 실행 | 준비 | |
| 2 | 실행 | 준비 | |
| 3 | 실행 | 준비 | |
| 4 | 실행 | 준비 | Process0 종료 |
| 5 | 실행 | ||
| 6 | 실행 | ||
| 7 | 실행 | ||
| 8 | 실행 | Process1 종료 |
2. 프로세스 상태 추이: CPU 이용과 입출력 작업을 할 때
| 시간 | Process0 | Process1 | 비고 |
|---|---|---|---|
| 1 | 실행 | 준비 | |
| 2 | 실행 | 준비 | |
| 3 | 실행 | 준비 | Process0이 입출력을 시작한다. |
| 4 | 대기 | 실행 | Process0은 대기 상태가 되고, |
| 5 | 대기 | 실행 | Process1이 실행된다. |
| 6 | 대기 | 실행 | |
| 7 | 준비 | 실행 | Process0 입출력 종료 |
| 8 | 준비 | 실행 | Process1 종료 |
| 9 | 실행 | - | |
| 10 | 실행 | - | Process0 종료 |
자료구조 - Process 관리
운영체제(OS)가 시스템에서 실행 중인 **프로세스(Process)**들을 효율적으로 관리하기 위해서는 내부적으로 특정한 자료 구조들을 활용합니다. 이 자료 구조들은 프로세스의 상태와 문맥 정보를 저장하고, CPU 가상화의 핵심 메커니즘인 **문맥 교환(Context Switch)**을 가능하게 하는 기반을 제공합니다.
Process List
운영체제는 시스템 내의 Process 관리를 위해 Process List라는 자료구조로 관리한다.
- Process 상태 관리: Running, Ready, Blocked 상태들을 관리한다.
- e.g. 입출력이 끝나면 Blocked 된 Process를 깨우기와 같은 작업을 한다.
PCB(Process Control Block)
PCB는 Process 관리하기 위한 중요정보를 담고 있음.
예를 들어, xv6에서 proc이라는 구조체를 활용한다.
| 주요 정보 필드 | 내용 |
|---|---|
| 레지스터 문맥 (register context) | 프로세스가 중단되었을 때 해당 프로세스의 레지스터 값들(PC, 범용 레지스터 등)을 저장합니다. 문맥 교환 시 이 정보가 복원되어 실행을 재개합니다. |
프로세스 상태 (state) | 프로세스가 현재 어떤 상태(UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE 등)에 있는지를 나타냅니다. |
프로세스 ID (pid) | 프로세스의 고유 식별자입니다. |
| 메모리 관련 정보 | 프로세스의 주소 공간 크기 (sz), 커널 스택(kstack), 그리고 메모리 시작 주소(mem) 등의 메모리 관련 정보가 포함됩니다. |
| 기타 정보 | 부모 프로세스 포인터, 파일 디스크립터 목록 (ofile), 현재 작업 디렉터리(cwd), 트랩 프레임 (tf) 등이 포함됩니다. |
문맥 교환을 위한 정보 저장
PCB 내에 저장된 레지스터 문맥 정보는 운영체제가 CPU 가상화를 구현하는 데 결정적인 역할을 한다.
- 운영체제가 현재 실행 중인 프로세스를 중단시키기로 결정하면 (예: 타이머 인터럽트 발생 시), 해당 프로세스의 레지스터 값들이 PCB에 저장됩니다.
- 이후 다른 프로세스를 실행시키기 위해 운영체제는 PCB에 저장된 다음 프로세스의 레지스터 값을 CPU의 물리 레지스터에 복원합니다.
- 이러한 저장 및 복원 작업을 **문맥 교환(context switch)**이라고 하며, 이를 통해 운영체제는 프로세스들에게 마치 독립적인 CPU를 사용하는 듯한 환상(시분할)을 제공합니다.
프로세스 상태와 종료 관리
PCB는 프로세스의 생명 주기 전반을 관리하는 데 사용된다.
- 상태 변천: 프로세스는 실행, 준비, 대기 상태 사이를 전이하며, PCB의 상태 필드는 이 변천을 반영한다.
- 종료 상태 (Zombie): 프로세스가 종료되더라도 PCB는 바로 제거되지 않고 ‘최종(final)’ 상태, 즉 Unix 기반 시스템에서는 좀비(zombie) 상태로 남아 있을 수 있다. 이 상태는 부모 프로세스가 자식 프로세스의 종료 상태나 반환 값(예: 종료 코드)을 검사할 수 있도록 정보를 유지한다. 부모 프로세스가
wait()시스템 콜을 호출하여 자식 프로세스가 종료되었음을 확인하고 관련 자원들을 정리하도록 운영체제에 알리는 시점에 PCB는 해제된다.