---
# System prepended metadata

title: 프로세스(Process)
tags: [과외(기태)]

---

# 프로세스(Process)

## 프로세스의 개념

![](https://hackmd.io/_uploads/BJi828jdT.png)

**컴퓨터에서 실행 중인 프로그램**

> | 프로그램 | 프로세스 |
> | -------- | -------- |
> |어떤 작업을 하기 위해 실행할 수 있는 파일|실행되어 작업중인 컴퓨터 프로그램|
> |파일이 저장 장치에 있지만 메모리에는 올라가 있지 않은 정적인 상태|메모리에 적재되고 CPU 자원을 할당받아 프로그램이 실행되고 있는 상태|
> |쉽게 말해 그냥 코드 덩어리|그 코드 덩어리를 실행한 것|

## 프로세스의 특징

![](https://i.imgur.com/tiltJnY.png)

- 메모리에 올라와 실행되고 있는 프로그램의 인스턴스(독립적인 개체)
- 프로세스는 각각 독립된 메모리 영역(Code, Data, Stack, Heap의 구조)을 할당받는다.
- 기본적으로 프로세스당 최소 1개의 스레드(메인 스레드)를 가지고 있다.
- 각 프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없다.
- 한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간의 통신(IPC, inter-process communication)을 사용해야 한다.
- 운영체제는 컴퓨터의 자원과 하드웨어를 효율적으로 관리하기 위해 여러 개의 프로세스를 동시에 실행할 수 있다.

## 프로세스 제어

- CPU 개수가 부족하더라도 여러 프로세스를 동시에 실행할 수 있는 이유는, CPU 스케줄링을 통해 여러 프로세스를 번갈아가며 실행하기 때문이다.
  - 아주 빠른 시간 간격으로 번갈아가며 실행되는 것처럼 보이기 때문에, 사용자는 여러 프로세스가 동시에 실행되는 것처럼 느낀다.
- 각 프로세스들은 CPU에 의해 동작을 수행하고, 일정 시간 뒤 다른 프로세스가 실행된다.
  - 물론 이런 과정은 OS에 의해 관리되며, 이 과정을 **CPU 스케줄링**이라고 한다.

## PCB(Process Control Block)

![image](https://hackmd.io/_uploads/Bk6hdcNp6.png)
![image](https://hackmd.io/_uploads/SyJDsCBpa.png)

- 프로세스 제어 블록
- 운영체제가 각 프로세스를 관리하기 위해 프로세스당 유지하는 정보를 담고 있는 자료구조
  - 프로세스의 상태, 프로그램 카운터, CPU 레지스터, CPU 일정 등의 정보를 포함한다.
- 프로그램 생성 시 운영체제에 의해 PCB가 생성되며, 프로세스가 완료되면 PCB도 제거된다.

### PCB에 저장되는 정보

![image](https://hackmd.io/_uploads/SkZFo0Spp.png)

- 프로세스 ID (PID) : 프로세스를 식별하기 위한 고유한 ID
- 레지스터 값 : 프로세스의 레지스터 상태
  - 프로세스가 일시 중지되었을 때, 어디까지 실행되다가 중지되었는지, 다시 실행할 때 어디부터 실행해야 하는지 등의 정보를 담는다
- 프로세스 상태 : 생성, 준비, 실행, 대기, 완료 등의 상태
- 스케줄링 정보 : 프로세스의 우선순위, 스케줄 큐 등의 정보
- 메모리 관리 정보 : 메모리 영역의 크기, 메모리 영역의 위치 등의 정보
- 등등

## 프로세스 스케줄링 기법

- FCFS(First-Come, First-Served): 먼저 도착한 프로세스가 먼저 처리된다. 공평하지만 평균 대기 시간이 길 수 있다.
- SJF(Shortest Job First): 가장 짧은 실행 시간을 가진 프로세스가 먼저 처리된다. 평균 대기 시간을 최소화하지만, 긴 작업이 계속 대기할 수 있는 기아 현상이 발생할 수 있다.
- Priority Scheduling: 각 프로세스에 우선순위를 부여하고, 높은 우선순위의 프로세스가 먼저 처리된다. 중요한 작업을 먼저 처리할 수 있지만, 낮은 우선순위의 작업은 기아 현상이 발생할 수 있다.
- Round Robin: 각 프로세스에 동일한 시간 할당량(time quantum)을 부여하고, 순환하며 처리한다. 공평한 스케줄링이 가능하지만, 시간 할당량 설정에 따라 성능이 달라질 수 있다.

> 현재 일반적인 OS는 다중 프로세스 및 다중 스레드를 지원하는 멀티태스킹 운영체제로, 여러 개의 프로세스 및 스레드를 동시에 실행한다. 그리고일반적으로 우선순위 기반 스케줄링과 Round-Robin 스케줄링이 결합된 형태인 다중 큐 스케줄링이 사용된다.

## 프로세스의 상태

![](https://hackmd.io/_uploads/BkBFjqEaa.png)

- 프로세스는 생성되어 완료될 때까지 여러 상태를 거친다.

1. 생성 상태 (New)
   - 프로세스가 막 생성되어 메모리에 적재되고, PCB를 할당 받은 상태
2. 준비 상태(Ready)
   - CPU를 할당받아 실행되기를 기다리는 상태
   - 준비 상태의 프로세스들은 준비 큐(Ready Queue)에 위치하며, 스케줄러에 의해 실행 상태로 전환될 때를 기다린다
   - 자신의 차례가 되어 CPU를 할당받으면 실행 상태로 전환된다
3. 실행 상태(Running)
   - CPU를 할당받아 실행 중인 상태
   - CPU 사용시간이 만료되면 다시 준비 상태로 전환된다
   - 입출력 요청이 발생하면 대기 상태로 전환된다
     - 입출력 요청이 발생하면 CPU를 사용하지 않기 때문에, 다른 프로세스가 CPU를 사용할 수 있도록 하기 위함
   - 모든 작업을 완료하면 종료 상태로 전환된다
4. 대기 상태(Waiting)
   - 프로세스가 실행 도중 입출력을 사용하거나, 다른 이벤트를 기다리는 상태
   - I/O 작업이 완료되거나 이벤트가 발생하면 준비 상태로 전환된다
5. 종료 상태(Terminated)
   - 프로세스가 작업을 모두 완료한 상태. 이 상태에서 프로세스는 메모리에서 해제되고, 관련 자원들이 반환된다.

## 프로세스의 자원공유

![image](https://hackmd.io/_uploads/rkiRhAS66.png)

- 프로세스는 기본적으로 독립된 주소 공간을 가지며, 한 프로세스가 다른 프로세스의 메모리에 직접 접근할 수 없다.
- 서로 데이터 공유가 필요한 프로세스는 프로세스 간의 통신(IPC, Inter-Process Communication)을 통해 데이터를 주고받을 수 있다.

## 프로세스 계층 구조

![image](https://hackmd.io/_uploads/SkHPCqNpT.png)

- 프로세스 실행 도중 (시스템 호출을 통해) 다른 프로세스를 생성할 수 있다.
- 새 프로세스를 생성한 프로세스 : 부모 프로세스
- 부모 프로세스에 의해 새로 생성된 프로세스 : 자식 프로세스
- 부모 프로세스와 자식 프로세스는 별개의 프로세스이므로 각기 다른 PCB를 가지고 있다.
  - 일부 운영체제는 자식 프로세스 PCB에 부모 프로세스의 정보를 저장한다.
  - PPID (Parent Process ID) : 부모 프로세스의 PID를 나타내는 값

### 프로세스 생성 기법

- 많은 운영체제에서 프로세스 생성 시 fork, 와 exec 시스템 호출을 사용한다.
  - fork() : 새로운 프로세스를 복사하는 시스템 호출
  - exec() : 자신의 주소 공간을 새로운 프로세스의 주소 공간으로 대체하는 시스템 호출

### fork 시스템 호출

![image](https://hackmd.io/_uploads/B1xK1iN6p.png)

- fork() : 자기 자신과 동일한 프로세스를 복제하여 새로운 프로세스를 생성하는 히스템 호출
  - 부모 프로세스와 자식 프로세스는 동일한 프로그램을 실행한다.
    - 프로세스 ID, 메모리 주소 등은 다르다.

### exec 시스템 호출

![image](https://hackmd.io/_uploads/S1MZejETa.png)

- exec() : 현재 프로세스의 주소 공간을 새로운 프로세스의 주소 공간으로 대체하는 시스템 호출
  - 새로운 프로세스를 실행하기 위해 기존 프로세스의 메모리를 새로운 프로세스의 메모리로 덮어쓴다.
  - 따라서, fork()로 생성된 자식 프로세스는 exec()를 통해 다른 프로그램을 실행할 수 있다.

> 유닉스 계열 운영체제에서는 `fork()`, `exec()`를 사용하지만, 윈도우 운영체제에서는 `CreateProcess()` 함수를 사용한다.

# 문맥 교환 (Context Switching)

![](https://i.imgur.com/1ef9S0x.png)

**운영 체제에서 실행 중인 프로세스나 스레드를 일시 중지하고, 다른 프로세스나 스레드를 실행하는 것**

- 멀티태스킹(Multitasking)을 가능하게 하기 위한 목적으로, 여러 개의 프로세스나 스레드를 동시에 실행할 수 있도록 한다
- 컨텍스트 스위칭이 발생하는 조건
  1. 다른 프로세스나 스레드를 실행시키기 위해 CPU 자원이 필요한 경우
  2. 현재 실행 중인 프로세스나 스레드가 입출력 작업 등의 블로킹 상태에 빠진 경우
  3. 타이머 인터럽트 등의 이벤트가 발생하여 실행 중인 프로세스나 스레드를 일시 중지해야 하는 경우

## 컨텍스트 스위칭 과정

![image](https://hackmd.io/_uploads/S1xa9cETa.png)

1. CPU는 Process P1을 실행한다 (Executing)
2. 일정 시간이 지나 Interrupt 또는 system call이 발생한다. (CPU는 idle 상태)
3. 현재 실행 중인 Process P1의 상태를 PCB1에 저장한다. (Save state into PCB1)
4. 다음으로 실행할 Process P2를 선택한다. (CPU 스케줄링)
5. Process P2의 상태를 PCB2에서 불러온다. (Reload state from PCB2)
6. CPU는 Process P2를 실행한다. (Executing)
7. 일정 시간이 지나  Interrupt 또는 system call이 발생한다. (CPU는 idle 상태)
8. 현재 실행 중인 Process P2의 상태를 PCB2에 저장한다. (Save state into PCB2)
9. 다시 Process P1을 실행할 차례가 된다. (CPU 스케줄링)
10. Process P1의 상태를 PCB1에서 불러온다. (Reload state from PCB1)
11. CPU는 Process P1을 중간 시점 부터 실행한다. (Executing)

## 컨텍스트 스위칭의 비용

![image](https://hackmd.io/_uploads/H1Akh0B6a.png)

- 컨텍스트 스위칭은 CPU가 다른 프로세스나 스레드로 전환하는 과정으로, 많은 시간과 자원을 소모한다.
  - PCB 저장 및 복원 비용
  - CPU 캐시 메모리 무효화에 따른 비용
  - 프로세스 스케쥴링 비용
  - 등등
- 컨텍스트 스위칭이 자주 발생하면, 시스템의 성능이 저하될 수 있다.
- 따라서 컨텍스트 스위칭을 최소화하기 위해, 스케줄링 알고리즘을 효율적으로 설계하는 것이 중요하다.
- 컨텍스트 스위칭은 다음과 같은 경우에 발생한다.
  - I/O 작업이 많은 프로그램
  - 멀티태스킹 환경에서 여러 프로세스나 스레드가 동시에 실행되는 경우
  - 타이머 인터럽트 등의 이벤트가 자주 발생하는 경우
