Skip to content

1주차

Baek HyeonBin edited this page Aug 5, 2026 · 4 revisions

1주차 - 프로세스와 스레드

학습 목표

이번 주차에서는 운영체제가 실행 중인 프로그램을 어떤 단위로 관리하는지 학습한다.

프로세스와 스레드의 차이를 이해하고, 운영체제가 이들의 실행 정보를 PCB와 TCB에 어떻게 저장하는지 살펴본다. 또한 CPU 실행 대상이 변경될 때 발생하는 Context Switching의 과정과 비용을 이해하고, 멀티프로세스와 멀티스레드 구조의 특징을 비교한다.

주요 학습 키워드는 다음과 같다.

  • 프로세스
  • 스레드
  • PCB
  • TCB
  • Context Switching
  • 멀티프로세스
  • 멀티스레드

핵심 개념

프로세스

프로세스는 실행 중인 프로그램이다.

프로그램은 디스크에 저장된 명령어와 데이터의 집합이지만, 프로세스는 프로그램이 메모리에 적재되어 CPU에 의해 실행되고 있는 동적인 상태를 의미한다.

디스크에 저장된 프로그램
          |
          | 실행
          v
메모리에 적재된 프로세스

하나의 프로그램을 여러 번 실행하면 동일한 프로그램을 기반으로 여러 개의 프로세스가 생성될 수 있다.

각 프로세스는 일반적으로 독립된 가상 주소 공간과 실행 상태를 가진다. 따라서 하나의 프로세스가 사용하는 메모리에 다른 프로세스가 임의로 접근할 수 없다.

프로세스가 가지는 정보

운영체제는 프로세스를 실행하고 관리하기 위해 다음과 같은 정보를 유지한다.

  • 프로세스 식별자
  • 현재 프로세스 상태
  • CPU 레지스터 값
  • 다음에 실행할 명령어의 주소
  • 메모리 관리 정보
  • 스케줄링 정보
  • 열린 파일 정보
  • 입출력 상태
  • 부모 프로세스와 자식 프로세스 정보
  • 사용자와 권한 정보

이러한 정보는 주로 PCB에 저장된다.


프로세스의 메모리 구조

프로세스의 가상 주소 공간은 일반적으로 Text, Data, BSS, Heap, Stack 영역으로 구성된다.

높은 주소
+----------------------------+
| Stack                      |
| 함수 호출 정보              |
| 매개변수, 지역 변수          |
+----------------------------+
|             ↓              |
|                            |
|             ↑              |
+----------------------------+
| Heap                       |
| 동적으로 할당된 메모리       |
+----------------------------+
| BSS                        |
| 초기화되지 않은 전역 변수     |
+----------------------------+
| Data                       |
| 초기화된 전역 변수           |
+----------------------------+
| Text                       |
| 실행할 프로그램 코드          |
+----------------------------+
낮은 주소

실제 메모리 배치와 영역의 위치는 운영체제, 실행 파일 형식, 컴파일러에 따라 달라질 수 있다.

Text 영역

프로세스가 실행할 명령어가 저장되는 영역이다.

실행 중인 코드가 임의로 변경되는 것을 방지하기 위해 일반적으로 읽기 전용으로 설정된다.

Data 영역

초기값이 존재하는 전역 변수와 정적 변수가 저장되는 영역이다.

프로그램이 시작될 때 할당되고 프로세스가 종료될 때 해제된다.

BSS 영역

초기화되지 않았거나 0으로 초기화되는 전역 변수와 정적 변수가 저장되는 영역이다.

실행 파일에 실제 초기값을 모두 저장하지 않아도 되므로 실행 파일의 크기를 줄일 수 있다.

Heap 영역

프로그램 실행 중 동적으로 할당되는 메모리 영역이다.

일반적으로 낮은 주소에서 높은 주소 방향으로 확장된다.

Heap 영역은 여러 스레드가 공유할 수 있으므로, 여러 스레드가 같은 데이터에 동시에 접근하면 동기화 문제가 발생할 수 있다.

Stack 영역

함수 호출 정보, 매개변수, 지역 변수, 반환 주소 등이 저장되는 영역이다.

함수가 호출되면 Stack Frame이 생성되고, 함수 실행이 끝나면 해당 Stack Frame이 제거된다.

프로세스 안에 여러 스레드가 존재하면 각 스레드는 독립적인 Stack을 가진다.


PCB

PCB는 Process Control Block의 약자로, 운영체제가 프로세스를 관리하기 위해 사용하는 자료구조다.

프로세스는 실행 중 CPU를 빼앗길 수 있다. 이후 해당 프로세스가 다시 CPU를 할당받았을 때 중단된 위치부터 실행하려면 이전 실행 상태가 저장되어 있어야 한다.

운영체제는 이러한 정보를 PCB에 저장한다.

PCB의 주요 정보

정보 설명
Process ID 프로세스를 식별하는 고유 번호
Process State New, Ready, Running, Waiting, Terminated 등의 상태
Program Counter 다음에 실행할 명령어의 주소
CPU Registers 범용 레지스터, Stack Pointer 등의 값
Scheduling Information 우선순위, 스케줄링 큐 위치, CPU 사용 시간
Memory Information 페이지 테이블, 세그먼트 정보, 주소 공간 정보
I/O Information 열린 파일, 할당된 장치, 입출력 상태
Accounting Information CPU 사용량, 실행 시간, 사용자 정보
Process Relationship 부모 프로세스와 자식 프로세스 정보

PCB가 필요한 이유

PCB가 없다면 프로세스가 CPU를 빼앗긴 후 어디까지 실행했는지 알 수 없다.

운영체제는 프로세스를 중단할 때 CPU 레지스터와 Program Counter 등의 값을 PCB에 저장하고, 다시 실행할 때 PCB의 값을 CPU에 복원한다.

프로세스 실행
     |
     | 중단
     v
CPU 상태를 PCB에 저장
     |
     | 다시 CPU 할당
     v
PCB의 상태를 CPU에 복원
     |
     v
중단 지점부터 실행

PCB의 저장 위치

PCB는 운영체제 커널이 관리하는 메모리 영역에 저장된다.

일반 사용자 프로세스가 PCB를 임의로 수정할 수 있다면 스케줄링 정보나 메모리 접근 권한이 손상될 수 있으므로 커널이 보호한다.


스레드

스레드는 프로세스 내부에서 실행되는 하나의 실행 흐름이다.

하나의 프로세스에는 최소 하나의 스레드가 존재한다. 프로세스 내부에 여러 스레드를 생성하면 하나의 프로세스가 여러 실행 흐름을 가질 수 있다.

프로세스
+------------------------------------+
| Code                               |
| Data                               |
| Heap                               |
| 열린 파일                           |
|                                    |
| Thread 1  Thread 2  Thread 3       |
| Stack 1   Stack 2   Stack 3        |
| Register 1 Register 2 Register 3   |
+------------------------------------+

스레드가 공유하는 자원

같은 프로세스에 속한 스레드는 일반적으로 다음 자원을 공유한다.

  • Code 영역
  • Data 영역
  • BSS 영역
  • Heap 영역
  • 프로세스의 가상 주소 공간
  • 열린 파일
  • 프로세스 단위의 운영체제 자원

스레드가 독립적으로 가지는 자원

각 스레드는 독립적인 실행 흐름을 유지하기 위해 다음 정보를 개별적으로 가진다.

  • Thread ID
  • Program Counter
  • CPU Register
  • Stack
  • 스레드 상태
  • 스레드 스케줄링 정보
  • Thread Local Storage

스레드가 Stack을 독립적으로 가지는 이유

각 스레드는 서로 다른 함수를 실행할 수 있다.

함수 호출 순서, 매개변수, 지역 변수, 반환 주소는 스레드마다 다르므로 각 스레드는 독립적인 Stack을 가져야 한다.

하나의 Stack을 공유하면 각 스레드의 함수 호출 기록과 지역 변수를 구분할 수 없다.


TCB

TCB는 Thread Control Block의 약자로, 운영체제가 스레드를 관리하기 위해 사용하는 자료구조다.

TCB에는 스레드의 실행 상태와 Context Switching에 필요한 정보가 저장된다.

TCB의 주요 정보

정보 설명
Thread ID 스레드를 식별하는 고유 번호
Thread State Ready, Running, Waiting 등의 상태
Program Counter 다음에 실행할 명령어의 주소
CPU Registers 스레드가 사용하던 레지스터 값
Stack Pointer 현재 Stack의 위치
Scheduling Information 우선순위, CPU 사용 시간, 스케줄링 큐 정보
Thread Local Storage 스레드마다 독립적으로 유지되는 데이터
Process Reference 스레드가 속한 프로세스의 정보

멀티프로세스

멀티프로세스는 하나의 시스템에서 여러 프로세스를 동시에 또는 번갈아 실행하는 구조다.

각 프로세스는 독립된 주소 공간과 자원을 가진다.

Process A                Process B
+---------------+        +---------------+
| Code          |        | Code          |
| Data          |        | Data          |
| Heap          |        | Heap          |
| Stack         |        | Stack         |
+---------------+        +---------------+
        |                        |
        +------ IPC 필요 --------+

IPC

IPC는 Inter-Process Communication의 약자로, 서로 다른 프로세스가 데이터를 주고받는 방법이다.

프로세스는 기본적으로 주소 공간이 분리되어 있기 때문에 명시적인 통신 수단이 필요하다.

파이프

한 프로세스의 출력 데이터를 다른 프로세스의 입력으로 전달하는 방식이다.

일반 파이프는 주로 부모와 자식처럼 관계가 있는 프로세스 사이에서 사용된다.

Named Pipe

파일 시스템에 이름을 가진 파이프를 생성하는 방식이다.

서로 직접적인 부모·자식 관계가 없는 프로세스도 사용할 수 있다.

메시지 큐

운영체제가 관리하는 큐에 메시지를 저장하고 다른 프로세스가 해당 메시지를 읽는 방식이다.

송신 프로세스와 수신 프로세스가 동시에 실행되지 않아도 통신할 수 있다.

공유 메모리

여러 프로세스가 같은 물리 메모리 영역을 자신의 주소 공간에 매핑하여 사용하는 방식이다.

데이터 복사 비용이 적어 빠르지만, 여러 프로세스가 같은 데이터를 수정할 수 있으므로 별도의 동기화가 필요하다.

소켓

네트워크 통신 인터페이스를 이용해 프로세스 간 데이터를 주고받는 방식이다.

같은 컴퓨터의 프로세스뿐 아니라 서로 다른 컴퓨터의 프로세스 사이에서도 통신할 수 있다.

시그널

운영체제가 프로세스에 특정 이벤트가 발생했음을 알리는 방식이다.

전달할 수 있는 정보의 양은 제한적이며, 주로 프로세스 제어나 이벤트 통지에 사용된다.


멀티스레드

멀티스레드는 하나의 프로세스 내부에 여러 스레드를 두어 여러 실행 흐름을 처리하는 구조다.

같은 프로세스의 스레드는 Code, Data, Heap, 열린 파일 등을 공유한다.

하나의 프로세스
+-----------------------------------+
| 공유 영역                         |
| Code, Data, Heap, 열린 파일        |
|                                   |
| Thread 1 | Thread 2 | Thread 3    |
| Stack 1  | Stack 2  | Stack 3     |
+-----------------------------------+

경쟁 상태

경쟁 상태는 여러 프로세스 또는 스레드가 공유 데이터에 동시에 접근할 때 실행 순서에 따라 결과가 달라지는 상황이다.

다음 연산을 두 스레드가 동시에 실행한다고 가정한다.

count = count + 1

이 연산은 내부적으로 다음과 같이 분리될 수 있다.

1. 메모리에서 count 값을 읽는다.
2. 읽은 값에 1을 더한다.
3. 결과를 메모리에 저장한다.

초기값이 0일 때 두 스레드가 동시에 0을 읽으면 각각 1을 계산한 뒤 1을 저장할 수 있다.

Thread A: count 읽기 → 0
Thread B: count 읽기 → 0
Thread A: 0 + 1 → 1 저장
Thread B: 0 + 1 → 1 저장

두 번 증가했지만 최종 결과는 1이 된다.

이를 Lost Update라고 한다.

임계 구역

임계 구역은 여러 실행 흐름이 동시에 접근하면 문제가 발생할 수 있는 코드 영역이다.

임계 구역에는 한 번에 하나의 실행 흐름만 진입하도록 제어해야 한다.

상호 배제

상호 배제는 하나의 실행 흐름이 임계 구역을 실행하는 동안 다른 실행 흐름이 진입하지 못하게 하는 성질이다.

대표적인 동기화 기법은 다음과 같다.

  • Mutex
  • Semaphore
  • Monitor
  • Spin Lock
  • Read-Write Lock
  • 원자적 연산

핵심 정리

키워드 핵심 내용
프로세스 실행 중인 프로그램이며 독립된 주소 공간과 자원을 가진다.
스레드 프로세스 내부의 실행 흐름이며 같은 프로세스의 자원을 공유한다.
PCB 프로세스의 상태와 실행 정보를 저장하는 운영체제 자료구조다.
TCB 스레드의 상태와 실행 정보를 저장하는 운영체제 자료구조다.
Context Switching 현재 실행 상태를 저장하고 다음 실행 상태를 복원하는 과정이다.
멀티프로세스 여러 독립 프로세스를 이용하며 장애 격리에 유리하다.
멀티스레드 하나의 프로세스에서 자원을 공유하며 여러 실행 흐름을 처리한다.
IPC 독립된 프로세스 사이에서 데이터를 전달하는 방법이다.
경쟁 상태 공유 데이터에 대한 실행 순서에 따라 결과가 달라지는 문제다.
동시성 여러 작업이 일정 시간 범위에서 함께 진행되는 성질이다.
병렬성 여러 작업이 실제로 같은 시점에 실행되는 성질이다.

동작 흐름

프로세스 상태

프로세스는 생성된 뒤 항상 CPU를 사용하고 있는 것이 아니다.

CPU 할당을 기다리거나 입출력 작업의 완료를 기다리면서 여러 상태를 이동한다.

대표적인 프로세스 상태는 다음과 같다.

상태 설명
New 프로세스가 생성되고 있는 상태
Ready CPU를 할당받으면 바로 실행할 수 있는 상태
Running CPU를 할당받아 명령어를 실행하고 있는 상태
Waiting 또는 Blocked 입출력이나 특정 이벤트가 완료되기를 기다리는 상태
Terminated 실행이 끝나거나 종료된 상태
stateDiagram-v2
    [*] --> New
    New --> Ready: 생성 완료
    Ready --> Running: CPU 할당
    Running --> Ready: 선점 또는 시간 할당량 만료
    Running --> Waiting: 입출력 요청 또는 이벤트 대기
    Waiting --> Ready: 입출력 또는 이벤트 완료
    Running --> Terminated: 실행 종료
    Terminated --> [*]
Loading

Ready 상태와 Waiting 상태

Ready 상태와 Waiting 상태는 모두 CPU를 사용하지 않는 상태지만, CPU를 사용하지 못하는 이유가 다르다.

Ready 상태

실행에 필요한 모든 준비가 끝났지만 다른 프로세스가 CPU를 사용하고 있어 기다리는 상태다.

CPU만 할당되면 즉시 실행할 수 있다.

Waiting 상태

입출력 작업이나 특정 이벤트가 완료되지 않아 실행을 계속할 수 없는 상태다.

Waiting 상태의 프로세스는 CPU를 할당받아도 필요한 조건이 충족되지 않았기 때문에 작업을 진행할 수 없다.

상태 전이 과정

프로세스 상태는 다음과 같은 원인으로 전환된다.

  • New에서 Ready: 프로세스 생성이 완료됨
  • Ready에서 Running: 스케줄러가 프로세스에 CPU를 할당함
  • Running에서 Ready: 시간 할당량이 끝나거나 다른 프로세스에 의해 선점됨
  • Running에서 Waiting: 입출력 작업이나 이벤트를 요청함
  • Waiting에서 Ready: 기다리던 입출력이나 이벤트가 완료됨
  • Running에서 Terminated: 프로세스 실행이 종료됨

프로세스 큐

운영체제는 프로세스의 상태에 따라 프로세스를 여러 큐에 저장한다.

Job Queue

시스템에 존재하는 전체 프로세스를 관리하는 큐다.

Ready Queue

메모리에 적재되어 있으며 CPU를 할당받기를 기다리는 프로세스가 저장된다.

CPU 스케줄러는 Ready Queue에서 다음에 실행할 프로세스를 선택한다.

Waiting Queue

입출력이나 특정 이벤트의 완료를 기다리는 프로세스가 저장된다.

기다리던 작업이 완료되면 프로세스는 Waiting Queue에서 제거되어 Ready Queue로 이동한다.

              CPU 할당
Ready Queue -------------> Running
    ^                         |
    |                         | 입출력 요청
    |                         v
    +------------------- Waiting Queue
          입출력 완료

프로세스 생성

운영체제는 새로운 프로그램을 실행할 때 프로세스를 생성한다.

Unix 계열 운영체제에서는 대표적으로 fork()exec()를 사용한다.

fork

fork()는 현재 실행 중인 부모 프로세스를 기반으로 자식 프로세스를 생성한다.

자식 프로세스는 부모 프로세스의 주소 공간을 기반으로 생성되지만, 논리적으로는 독립된 주소 공간을 가진다.

부모 프로세스
     |
     | fork()
     v
부모 프로세스 + 자식 프로세스

초기에는 부모와 자식이 같은 메모리 내용을 가진 것처럼 보이지만, 한쪽에서 메모리를 수정하면 다른 쪽의 메모리가 함께 변경되지는 않는다.

많은 운영체제는 실제 메모리 복사 비용을 줄이기 위해 Copy-on-Write 방식을 사용한다.

Copy-on-Write

Copy-on-Write는 fork() 직후 부모와 자식이 물리 메모리 페이지를 공유하고, 어느 한쪽이 해당 페이지를 수정할 때 실제 복사를 수행하는 방식이다.

fork 직후

부모 가상 주소 ─┐
                ├── 동일한 물리 페이지
자식 가상 주소 ─┘

한쪽이 페이지 수정

부모 가상 주소 ─── 부모용 물리 페이지
자식 가상 주소 ─── 복사된 자식용 물리 페이지

이 방식을 사용하면 자식 프로세스를 생성할 때 전체 메모리를 즉시 복사하지 않아도 된다.

exec

exec() 계열 시스템 콜은 현재 프로세스의 주소 공간을 새로운 프로그램의 코드와 데이터로 교체한다.

exec()는 새로운 프로세스를 생성하는 것이 아니라, 현재 프로세스가 실행하는 프로그램을 다른 프로그램으로 변경한다.

부모 프로세스
     |
     | fork()
     v
자식 프로세스
     |
     | exec()
     v
새로운 프로그램 실행

프로세스 종료

프로세스는 작업을 완료하거나 오류가 발생하면 종료된다.

프로세스가 종료되면 운영체제는 해당 프로세스가 사용하던 메모리와 자원을 회수한다.

Unix 계열 운영체제에서는 자식 프로세스가 종료되더라도 부모 프로세스가 종료 상태를 확인할 때까지 일부 정보가 프로세스 테이블에 남을 수 있다.

좀비 프로세스

자식 프로세스가 종료되었지만 부모 프로세스가 종료 상태를 회수하지 않은 상태다.

좀비 프로세스는 실행되지 않으며 대부분의 자원은 해제되었지만, 종료 상태와 프로세스 식별자 등의 정보가 프로세스 테이블에 남아 있다.

고아 프로세스

부모 프로세스가 자식 프로세스보다 먼저 종료되어 부모가 사라진 프로세스다.

운영체제는 일반적으로 특정 시스템 프로세스가 고아 프로세스를 대신 관리하도록 한다.


Context Switching

Context Switching은 CPU가 현재 실행 중인 프로세스 또는 스레드의 실행 상태를 저장하고, 다음 실행 대상의 상태를 복원하는 과정이다.

CPU는 한 시점에 하나의 실행 흐름만 수행할 수 있다. 여러 프로세스와 스레드를 번갈아 실행하려면 각 실행 흐름의 상태를 저장하고 복원해야 한다.

여기서 Context는 실행을 이어가기 위해 필요한 상태 정보를 의미한다.

Context에 포함되는 정보

  • Program Counter
  • Stack Pointer
  • CPU Register
  • CPU 상태 레지스터
  • 메모리 관리 정보
  • 스케줄링 정보
  • 실행 상태

Context Switching 과정

1. 프로세스 A가 CPU에서 실행된다.
2. 인터럽트나 스케줄링 이벤트가 발생한다.
3. 운영체제가 프로세스 A의 Context를 PCB 또는 TCB에 저장한다.
4. 스케줄러가 다음에 실행할 프로세스 B를 선택한다.
5. 프로세스 B의 Context를 PCB 또는 TCB에서 복원한다.
6. CPU가 프로세스 B를 이전 중단 지점부터 실행한다.
sequenceDiagram
    participant A as Process A
    participant OS as Operating System
    participant B as Process B

    A->>OS: 실행 중 인터럽트 또는 선점 발생
    OS->>OS: A의 Context 저장
    OS->>OS: 다음 실행 대상 선택
    OS->>OS: B의 Context 복원
    OS->>B: B 실행 재개
Loading

Context Switching이 발생하는 경우

  • CPU 시간 할당량이 만료된 경우
  • 더 높은 우선순위의 프로세스가 Ready 상태가 된 경우
  • 실행 중인 프로세스가 입출력을 요청한 경우
  • 인터럽트가 발생한 경우
  • 프로세스가 Waiting 상태로 전환된 경우
  • 현재 프로세스가 종료된 경우
  • 실행 중인 스레드가 동기화 객체를 기다리는 경우

프로세스 Context Switching

프로세스 간 Context Switching이 발생하면 운영체제는 현재 프로세스의 CPU 상태를 PCB에 저장하고 다음 프로세스의 상태를 복원한다.

프로세스는 서로 다른 가상 주소 공간을 사용하므로 CPU 실행 상태뿐 아니라 메모리 주소 변환과 관련된 정보도 변경될 수 있다.

프로세스 전환 시 변경될 수 있는 정보

  • Program Counter
  • CPU Register
  • Stack Pointer
  • 페이지 테이블 기준 정보
  • 가상 주소 공간
  • 스케줄링 상태
  • 커널 Stack
  • 메모리 보호 정보

프로세스가 변경되면 CPU Cache와 TLB에 저장된 정보의 활용도가 낮아질 수 있다.


스레드 Context Switching

스레드 간 Context Switching에서는 현재 스레드의 실행 상태를 TCB에 저장하고 다음 스레드의 상태를 복원한다.

같은 프로세스의 스레드 간 전환

같은 프로세스에 속한 스레드는 주소 공간과 여러 프로세스 자원을 공유한다.

따라서 일반적으로 다음 정보는 그대로 유지될 수 있다.

  • 가상 주소 공간
  • Code 영역
  • Data 영역
  • Heap 영역
  • 열린 파일

변경되는 주요 정보는 다음과 같다.

  • Program Counter
  • CPU Register
  • Stack Pointer
  • 스레드 상태
  • 스케줄링 정보

서로 다른 프로세스의 스레드 간 전환

서로 다른 프로세스에 속한 스레드 사이에서 전환이 발생하면 스레드의 실행 상태뿐 아니라 프로세스의 주소 공간과 메모리 관리 정보도 함께 변경될 수 있다.

따라서 같은 프로세스에 속한 스레드 간 전환보다 비용이 커질 가능성이 높다.


Context Switching이 오버헤드인 이유

Context Switching은 애플리케이션의 실제 작업을 수행하지 않는다.

운영체제가 다음 실행 대상을 선택하고, 현재 상태를 저장하고, 새로운 상태를 복원하는 동안 CPU는 원래 프로그램의 연산을 진행하지 못한다.

직접적인 비용

  • CPU Register 저장
  • Program Counter 저장
  • Stack Pointer 저장
  • PCB 또는 TCB 갱신
  • 다음 실행 대상 선택
  • 새로운 Context 복원

간접적인 비용

  • CPU Cache 적중률 감소
  • TLB 적중률 감소
  • 파이프라인 무효화
  • 분기 예측 정보 활용도 감소
  • 커널 스케줄러 실행 비용

Context Switching이 많아지는 경우

  • 실행 가능한 프로세스와 스레드 수가 지나치게 많을 때
  • CPU 시간 할당량이 지나치게 짧을 때
  • 입출력 대기가 자주 발생할 때
  • Lock 경쟁이 심할 때
  • 우선순위가 다른 작업이 자주 선점할 때

프로세스와 스레드의 수를 늘린다고 항상 성능이 좋아지는 것은 아니다. 실행 단위가 지나치게 많으면 Context Switching 비용이 증가해 전체 처리 성능이 낮아질 수 있다.


개념 비교

프로그램과 프로세스의 차이

구분 프로그램 프로세스
의미 실행 가능한 명령어와 데이터의 집합 실행 중인 프로그램
상태 정적 동적
저장 위치 주로 보조 기억장치 주로 주기억장치
실행 상태 없음 CPU 실행 상태를 가짐
자원 실행 자원을 직접 보유하지 않음 메모리, 파일, 레지스터 상태 등의 자원을 보유
개수 하나의 프로그램 파일 하나의 프로그램으로 여러 프로세스 생성 가능

PCB와 TCB

PCB와 TCB의 관계

PCB는 프로세스 단위의 자원과 상태를 저장하고, TCB는 스레드 단위의 실행 상태를 저장한다.

PCB
├── 프로세스 ID
├── 주소 공간 정보
├── 열린 파일 정보
├── 프로세스 권한
├── TCB 1
├── TCB 2
└── TCB 3

하나의 프로세스에 여러 스레드가 존재하면 하나의 PCB와 여러 개의 TCB가 연결될 수 있다.

다만 PCB와 TCB의 구체적인 구성과 관계는 운영체제 구현에 따라 다르다. 일부 운영체제는 프로세스와 스레드를 공통 실행 단위로 표현하고 하나의 자료구조 안에서 관리하기도 한다.

PCB와 TCB 비교

구분 PCB TCB
전체 이름 Process Control Block Thread Control Block
관리 대상 프로세스 스레드
저장 정보 주소 공간, 열린 파일, 프로세스 상태, 권한 레지스터, Program Counter, Stack Pointer, 스레드 상태
생성 개수 일반적으로 프로세스마다 하나 일반적으로 스레드마다 하나
공유 관계 프로세스 전체 자원 관리 같은 프로세스의 PCB와 자원 정보를 참조

프로세스와 스레드 비교

비교 기준 프로세스 스레드
의미 실행 중인 프로그램이자 자원 관리 단위 프로세스 내부의 실행 흐름
주소 공간 프로세스마다 독립적 같은 프로세스의 주소 공간 공유
Code 영역 프로세스마다 독립적 같은 프로세스의 스레드가 공유
Data 영역 프로세스마다 독립적 같은 프로세스의 스레드가 공유
Heap 영역 프로세스마다 독립적 같은 프로세스의 스레드가 공유
Stack 영역 프로세스마다 독립적 스레드마다 독립적
Program Counter 프로세스 실행 흐름에 필요 스레드마다 독립적으로 보유
CPU Register 실행 단위별로 저장 스레드마다 독립적으로 보유
자원 공유 IPC가 필요함 공유 메모리에 직접 접근 가능
생성 비용 상대적으로 큼 상대적으로 작음
전환 비용 상대적으로 큼 같은 프로세스 내에서는 상대적으로 작음
장애 영향 다른 프로세스와 격리됨 하나의 스레드 오류가 전체 프로세스에 영향을 줄 수 있음
동기화 프로세스 간 통신 방식 필요 공유 자원에 대한 동기화 필요

프로세스가 자원을 독립적으로 가지는 이유

각 프로세스는 독립된 주소 공간을 사용한다.

한 프로세스에서 잘못된 메모리 접근이 발생해도 다른 프로세스의 메모리에 직접 영향을 주지 않도록 격리하기 위해서다.

스레드가 자원을 공유하는 이유

스레드는 하나의 프로세스 내부에서 여러 실행 흐름을 만들기 위한 단위다.

같은 작업에 필요한 코드와 데이터를 공유함으로써 메모리 사용량과 통신 비용을 줄일 수 있다.

하지만 여러 스레드가 같은 데이터에 동시에 접근하면 경쟁 상태가 발생할 수 있다.


사용자 수준 스레드와 커널 수준 스레드

스레드는 누가 스레드를 관리하고 스케줄링하는지에 따라 사용자 수준 스레드와 커널 수준 스레드로 구분할 수 있다.

사용자 수준 스레드

사용자 영역의 스레드 라이브러리가 스레드를 생성하고 관리한다.

커널은 개별 사용자 스레드의 존재를 직접 알지 못하고 하나의 프로세스 또는 제한된 수의 실행 단위만 인식할 수 있다.

장점
  • 커널 모드 전환 없이 스레드를 생성할 수 있다.
  • 스레드 생성과 전환 비용이 상대적으로 작다.
  • 운영체제와 무관한 스케줄링 정책을 구현할 수 있다.
단점
  • 하나의 스레드가 블로킹 시스템 콜을 호출하면 전체 프로세스가 대기할 수 있다.
  • 커널이 개별 스레드를 알지 못하면 여러 CPU 코어에 스레드를 직접 배치하기 어렵다.
  • 운영체제의 스케줄링 지원을 충분히 활용하기 어렵다.

커널 수준 스레드

운영체제 커널이 스레드를 직접 생성하고 관리한다.

커널은 각 스레드의 상태를 알고 있으며 스레드 단위로 CPU를 할당할 수 있다.

장점
  • 하나의 스레드가 대기 상태가 되어도 다른 스레드를 실행할 수 있다.
  • 여러 CPU 코어에 스레드를 배치하여 병렬 실행할 수 있다.
  • 운영체제의 스케줄링 기능을 활용할 수 있다.
단점
  • 스레드 생성과 관리에 커널이 개입한다.
  • 스레드 전환 시 사용자 모드와 커널 모드 사이의 전환이 필요할 수 있다.
  • 사용자 수준 스레드보다 관리 비용이 클 수 있다.

스레드 매핑 모델

Many-to-One

여러 사용자 스레드를 하나의 커널 스레드에 연결한다.

User Thread 1 ─┐
User Thread 2 ─┼── Kernel Thread 1
User Thread 3 ─┘

하나의 사용자 스레드가 블로킹되면 전체 스레드가 실행되지 못할 수 있으며, 여러 CPU 코어를 활용한 병렬 실행이 어렵다.

One-to-One

사용자 스레드 하나를 커널 스레드 하나에 연결한다.

User Thread 1 ─── Kernel Thread 1
User Thread 2 ─── Kernel Thread 2
User Thread 3 ─── Kernel Thread 3

여러 스레드를 병렬로 실행할 수 있지만, 많은 스레드를 생성하면 커널이 관리해야 하는 스레드 수도 증가한다.

Many-to-Many

여러 사용자 스레드를 여러 커널 스레드에 연결한다.

User Thread 1 ─┐    ┌── Kernel Thread 1
User Thread 2 ─┼────┤
User Thread 3 ─┤    └── Kernel Thread 2
User Thread 4 ─┘

사용자 수준 스레드의 유연성과 커널 수준 스레드의 병렬성을 함께 활용하는 방식이다.


Context Switching과 Mode Switching

Context Switching과 Mode Switching은 같은 개념이 아니다.

Mode Switching

CPU의 실행 권한이 사용자 모드와 커널 모드 사이에서 변경되는 것이다.

시스템 콜이나 인터럽트가 발생하면 사용자 모드에서 커널 모드로 전환될 수 있다.

Context Switching

현재 실행 중인 프로세스 또는 스레드를 다른 프로세스 또는 스레드로 변경하는 것이다.

시스템 콜이 발생하더라도 같은 프로세스가 계속 실행된다면 Mode Switching만 발생하고 Context Switching은 발생하지 않을 수 있다.

구분 Mode Switching Context Switching
변경 대상 CPU 권한 수준 실행 중인 프로세스 또는 스레드
대표 원인 시스템 콜, 예외, 인터럽트 선점, 입출력 대기, 스케줄링
상태 저장 일부 CPU 상태 저장 실행 Context 전체 저장 및 복원
실행 대상 변경 반드시 변경되는 것은 아님 다른 실행 대상으로 변경됨

IPC 비교

방식 특징 장점 단점
Pipe 단방향 바이트 스트림 구조가 단순함 관계가 있는 프로세스 중심
Named Pipe 이름이 있는 파이프 관계없는 프로세스도 사용 가능 파일 시스템 객체 관리 필요
Message Queue 메시지 단위 전달 비동기 통신 가능 커널 복사 비용 발생 가능
Shared Memory 메모리 직접 공유 데이터 전송 속도가 빠름 동기화가 필요함
Socket 통신 종단점 사용 원격 프로세스 통신 가능 프로토콜 처리 비용
Signal 이벤트 통지 간단한 제어 가능 전달 정보가 제한적

멀티스레드의 장단점

멀티스레드의 장점

자원 공유

같은 프로세스의 주소 공간을 공유하므로 데이터를 전달하기 위해 별도의 IPC를 사용할 필요가 적다.

낮은 생성 비용

프로세스 전체를 생성하는 것보다 스레드 실행 정보를 생성하는 비용이 일반적으로 작다.

상대적으로 낮은 전환 비용

같은 프로세스의 스레드 간에는 주소 공간을 공유하므로 프로세스 전환보다 변경해야 하는 정보가 적을 수 있다.

응답성 향상

하나의 스레드가 입출력을 기다리는 동안 다른 스레드가 작업을 수행할 수 있다.

병렬 실행

여러 CPU 코어가 있다면 여러 스레드를 서로 다른 코어에서 병렬로 실행할 수 있다.

멀티스레드의 단점

경쟁 상태

여러 스레드가 공유 데이터를 동시에 읽고 수정하면 실행 순서에 따라 결과가 달라질 수 있다.

동기화 필요

공유 데이터의 일관성을 유지하기 위해 Mutex, Semaphore, Monitor 등의 동기화 기법이 필요하다.

교착 상태

여러 스레드가 서로가 보유한 자원을 기다리면서 무한히 대기할 수 있다.

장애 전파

하나의 스레드에서 잘못된 메모리 접근이 발생하면 전체 프로세스가 종료될 수 있다.

디버깅의 어려움

스레드 실행 순서는 매번 달라질 수 있으므로 동시성 오류를 재현하기 어렵다.


멀티프로세스와 멀티스레드 비교

비교 기준 멀티프로세스 멀티스레드
실행 단위 여러 프로세스 하나의 프로세스 내부의 여러 스레드
주소 공간 각각 독립적 같은 프로세스의 주소 공간 공유
데이터 공유 IPC 필요 공유 메모리에 직접 접근
생성 비용 상대적으로 큼 상대적으로 작음
Context Switching 상대적으로 비용이 큼 같은 프로세스 내에서는 상대적으로 작음
메모리 사용량 상대적으로 큼 상대적으로 작음
장애 격리 높음 낮음
동기화 IPC 방식에 따라 필요 공유 자원 동기화가 중요
구현 난이도 통신 구조 설계가 필요 동시성 제어가 어려움
확장 방식 프로세스 단위 스레드 단위

멀티프로세스가 적합한 경우

  • 작업 간 높은 독립성이 필요한 경우
  • 하나의 작업 실패가 다른 작업에 영향을 주지 않아야 하는 경우
  • 보안과 권한 분리가 중요한 경우
  • 프로세스 단위의 병렬 처리가 필요한 경우

멀티스레드가 적합한 경우

  • 여러 실행 흐름이 데이터를 자주 공유해야 하는 경우
  • 실행 단위 생성 비용을 줄여야 하는 경우
  • 하나의 프로세스 내부에서 여러 작업을 동시에 처리해야 하는 경우
  • 공유 자원에 대한 동기화를 적절히 설계할 수 있는 경우

어떤 방식이 항상 더 우수한 것은 아니다.

독립성과 장애 격리가 중요하면 멀티프로세스가 유리하고, 자원 공유와 상대적으로 가벼운 실행 단위가 중요하면 멀티스레드가 유리하다.


동시성과 병렬성

멀티프로세스와 멀티스레드를 이해하려면 동시성과 병렬성을 구분해야 한다.

동시성

여러 작업이 일정한 시간 범위 안에서 함께 진행되는 성질이다.

단일 CPU 코어에서도 운영체제가 실행 대상을 빠르게 전환하면 여러 작업이 동시에 진행되는 것처럼 보일 수 있다.

시간 ─────────────────────────>

Task A  실행 ── 대기 ── 실행 ── 대기
Task B  대기 ── 실행 ── 대기 ── 실행

병렬성

여러 작업이 실제로 같은 시점에 실행되는 성질이다.

여러 CPU 코어를 사용하여 서로 다른 작업을 물리적으로 동시에 수행한다.

시간 ─────────────────────────>

Core 1  Task A ────────────────
Core 2  Task B ────────────────

동시성과 병렬성 비교

구분 동시성 병렬성
의미 여러 작업을 함께 다루는 구조 여러 작업을 실제로 동시에 실행
단일 코어 가능 일반적으로 불가능
다중 코어 가능 가능
핵심 실행 순서의 전환 물리적인 동시 실행
목적 응답성과 자원 활용 처리 시간 단축과 처리량 증가

멀티스레드를 사용한다고 반드시 병렬로 실행되는 것은 아니다.

스레드 수가 여러 개이더라도 CPU 코어가 하나라면 스레드는 Context Switching을 통해 번갈아 실행된다.


예상 질문

프로세스란 무엇인가요?

프로세스는 실행 중인 프로그램이다. 운영체제는 프로세스마다 독립된 가상 주소 공간과 CPU 실행 상태, 메모리 정보, 열린 파일 등의 자원을 관리한다.

프로그램과 프로세스의 차이는 무엇인가요?

프로그램은 디스크에 저장된 정적인 명령어와 데이터의 집합이고, 프로세스는 프로그램이 메모리에 적재되어 실행 중인 동적인 상태다. 하나의 프로그램으로 여러 프로세스를 생성할 수 있다.

프로세스의 메모리 영역을 설명해 주세요.

일반적으로 Text, Data, BSS, Heap, Stack 영역으로 구분한다. Text에는 실행 코드, Data에는 초기화된 전역 변수, BSS에는 초기화되지 않은 전역 변수, Heap에는 동적 할당 메모리, Stack에는 함수 호출 정보와 지역 변수가 저장된다.

프로세스의 Ready 상태와 Waiting 상태는 무엇이 다른가요?

Ready 상태는 CPU만 할당받으면 실행할 수 있는 상태다. Waiting 상태는 입출력이나 특정 이벤트가 완료되지 않아 CPU를 받아도 작업을 계속할 수 없는 상태다.

PCB란 무엇인가요?

PCB는 운영체제가 프로세스를 관리하기 위해 사용하는 자료구조다. 프로세스 ID, 상태, Program Counter, CPU Register, 메모리 정보, 스케줄링 정보, 열린 파일 정보 등이 저장된다.

PCB는 왜 필요한가요?

프로세스가 CPU를 빼앗긴 뒤 다시 실행될 때 이전 실행 위치와 CPU 상태를 복원해야 하기 때문이다. 운영체제는 프로세스의 Context를 PCB에 저장하고 이후 다시 CPU에 복원한다.

스레드란 무엇인가요?

스레드는 프로세스 내부에서 실행되는 하나의 실행 흐름이다. 같은 프로세스의 스레드는 Code, Data, Heap, 열린 파일 등을 공유하지만 Stack, Program Counter, CPU Register는 각각 독립적으로 가진다.

스레드가 Stack을 독립적으로 가지는 이유는 무엇인가요?

각 스레드는 서로 다른 함수를 실행하고 서로 다른 지역 변수와 함수 호출 기록을 가져야 하기 때문이다. Stack을 공유하면 스레드별 함수 실행 상태를 구분할 수 없다.

TCB란 무엇인가요?

TCB는 운영체제가 스레드를 관리하기 위해 사용하는 자료구조다. Thread ID, 스레드 상태, Program Counter, CPU Register, Stack Pointer, 스케줄링 정보 등이 저장된다.

PCB와 TCB의 차이는 무엇인가요?

PCB는 주소 공간, 열린 파일, 권한 등 프로세스 단위의 자원과 상태를 저장한다. TCB는 Program Counter, CPU Register, Stack Pointer 등 스레드 단위의 실행 상태를 저장한다. 하나의 프로세스에 여러 스레드가 있다면 하나의 PCB와 여러 TCB가 연결될 수 있다.

프로세스와 스레드의 차이는 무엇인가요?

프로세스는 독립된 주소 공간과 자원을 가지는 실행 단위다. 스레드는 프로세스 내부의 실행 흐름으로, 같은 프로세스에 속한 스레드끼리 주소 공간과 자원을 공유한다.

Context Switching이란 무엇인가요?

CPU가 현재 실행 중인 프로세스나 스레드의 상태를 PCB 또는 TCB에 저장하고, 다음 실행 대상의 상태를 복원하는 과정이다.

Context Switching은 왜 비용이 발생하나요?

CPU Register와 Program Counter를 저장하고 복원해야 하며, 스케줄러 실행과 PCB 또는 TCB 갱신이 필요하기 때문이다. 프로세스 전환에서는 주소 공간 변경으로 인해 Cache와 TLB의 활용도가 낮아질 수도 있다.

Mode Switching과 Context Switching의 차이는 무엇인가요?

Mode Switching은 CPU 권한이 사용자 모드와 커널 모드 사이에서 변경되는 것이다. Context Switching은 실행 중인 프로세스나 스레드가 다른 실행 대상으로 변경되는 것이다. Mode Switching이 발생하더라도 실행 대상이 같다면 Context Switching은 발생하지 않을 수 있다.

프로세스 간 Context Switching이 스레드 간 Context Switching보다 일반적으로 무거운 이유는 무엇인가요?

프로세스는 서로 다른 주소 공간을 사용하므로 CPU 상태뿐 아니라 메모리 관리 정보도 변경해야 할 수 있다. 같은 프로세스의 스레드는 주소 공간을 공유하므로 주로 Register, Program Counter, Stack Pointer 등의 실행 상태만 변경하면 된다.

멀티프로세스의 장단점은 무엇인가요?

장점은 프로세스 간 독립성이 높고 장애 격리와 보안에 유리하다는 것이다. 단점은 프로세스 생성과 Context Switching 비용이 크고, 데이터를 공유하려면 IPC가 필요하다는 것이다.

멀티스레드의 장단점은 무엇인가요?

장점은 자원을 쉽게 공유할 수 있고 생성 및 전환 비용이 상대적으로 작다는 것이다. 단점은 공유 데이터에 대한 경쟁 상태와 교착 상태가 발생할 수 있고, 하나의 스레드 오류가 전체 프로세스에 영향을 줄 수 있다는 것이다.

멀티프로세스와 멀티스레드 중 무엇이 더 좋은가요?

항상 한쪽이 더 좋은 것은 아니다. 장애 격리와 독립성이 중요하면 멀티프로세스가 적합하고, 자원 공유와 비교적 가벼운 실행 단위가 중요하면 멀티스레드가 적합하다. 작업 특성과 동기화 비용, 메모리 사용량, 장애 허용 범위를 함께 고려해야 한다.

동시성과 병렬성의 차이는 무엇인가요?

동시성은 여러 작업이 일정한 시간 범위 안에서 함께 진행되는 구조이고, 병렬성은 여러 작업이 실제로 같은 시점에 실행되는 것이다. 단일 코어에서도 동시성은 가능하지만 병렬성을 위해서는 일반적으로 여러 CPU 코어가 필요하다.


참고 자료

프로세스와 스레드

프로세스 생성과 종료

스레드와 스케줄링

프로세스 구현과 IPC

Clone this wiki locally