CHAPTER 06
운영체제
프로세스 상태, 메모리 구조, 컨텍스트 스위칭부터 가상메모리, 스케줄링, 데드락까지 — OS 핵심 개념을 인터랙티브 시각화로 완전히 이해합니다.
프로세스 상태메모리 레이아웃컨텍스트 스위칭
메모리 관리가상메모리스케줄링데드락
NEW
프로세스가 막 생성된 상태. OS가 PCB를 할당하고 초기화합니다.
READY
CPU를 받을 준비가 된 상태. 레디 큐에서 스케줄러를 기다립니다.
RUNNING
실제로 CPU에서 명령어가 실행 중인 상태. 단일 코어에서는 1개만 가능.
WAITING
I/O 완료, 이벤트 등을 기다리는 상태. CPU를 소비하지 않습니다.
TERMINATED
실행이 끝났거나 강제 종료된 상태. OS가 PCB와 자원을 회수합니다.
버튼을 눌러 프로세스의 상태를 전환해 보세요. 선택된 프로세스(파란 테두리)에 상태 전환이 적용됩니다.
💡 Tip: 실제 OS에서 NEW→READY는 fork()로, RUNNING→WAITING은 read()나 sleep() 같은 블로킹 시스템 콜로 발생합니다.
0xFFFF (High)
빈 공간
—
BSS
초기화 안 된 전역변수
DATA
초기화된 전역/정적 변수
CODE (TEXT)
읽기전용 실행 코드
0x0000 (Low)
포인터 현황
SP (스택 포인터)SP = 0xFFFF
HP (힙 포인터)HP = 0x4000
스택과 힙이 충돌 위험! Stack Overflow 또는 Heap Overflow 가능성이 있습니다.
세그먼트 설명
STACK함수 호출 시 지역변수, 반환주소, 매개변수 저장
HEAPmalloc/new로 동적 할당. 프로그래머가 직접 관리
BSSint g; 처럼 초기값 없는 전역변수 (0으로 자동초기화)
DATAint g=5; 처럼 초기값 있는 전역/static 변수
CODE컴파일된 기계어 명령어. 읽기 전용(쓰면 segfault)
💡 Tip: 재귀 함수를 무한히 호출하면 스택이 힙 방향으로 계속 자라다가 stack overflow가 발생합니다. C에서 free()를 잊으면 힙이 누수(memory leak)됩니다.
CPU 타임라인 (시간 →)
PCB — Process A
PID1
PC0x0040
SP0xFF80
AX0x0005
StateRUNNING
PCB — Process B
PID2
PC0x00A0
SP0xFE00
AX0x001F
StateREADY
💡 Tip: 컨텍스트 스위치는 CPU에 저장된 레지스터 전체(수십~수백 개)를 메모리에 쓰고 읽는 작업입니다. 이 오버헤드가 크기 때문에 OS는 타임슬라이스(quantum)를 너무 짧게 설정하지 않습니다.
메모리 상태: 비어있음 | 단편화: 0%
💡 Tip: 단편화 지수가 높을수록 비어있는 블록이 잘게 쪼개져 큰 프로세스를 할당하기 어렵습니다. 압축은 실행 중인 프로세스를 이동시켜야 하므로 비용이 큽니다.
가상 페이지를 클릭하거나 버튼을 눌러 접근을 시뮬레이션하세요.
💡 Tip: 물리 프레임이 꽉 찼을 때 FIFO 알고리즘은 가장 먼저 들어온 페이지를 교체합니다. 실제 OS는 LRU(가장 오래 미사용)나 Clock 알고리즘을 사용합니다.
레디 큐 (Ready Queue) — 실행 대기 중인 프로세스
스케줄러를 실행하면 레디 큐가 표시됩니다
Gantt 차트
💡 Tip: WT(대기시간) = 반환시간 - 버스트시간. TAT(반환시간) = 완료시간 - 도착시간. SJF는 starvation(기아) 문제가 있어 짧은 작업이 계속 오면 긴 작업은 영원히 기다릴 수 있습니다.
데드락 4가지 필요조건 — 클릭해서 체크/해제
☐
CONDITION 01
상호배제 (Mutual Exclusion)
자원은 한 번에 한 프로세스만 사용 가능. 포크는 한 철학자만 쥘 수 있습니다.
☐
CONDITION 02
점유 및 대기 (Hold & Wait)
자원을 점유한 채로 다른 자원을 기다림. 왼쪽 포크를 쥔 채 오른쪽 포크를 기다립니다.
☐
CONDITION 03
비선점 (No Preemption)
자원을 강제로 빼앗을 수 없음. 철학자가 포크를 자발적으로 내려놓을 때만 반납됩니다.
☐
CONDITION 04
순환 대기 (Circular Wait)
P0→R1→P1→R2→...→Pn→R0 처럼 프로세스들이 원형으로 서로를 기다립니다.
4가지 조건 중 0/4 충족 — 데드락 위험 없음
💡 해결책: (1) 순환 대기 제거 — 홀수 철학자는 오른쪽 먼저, 짝수는 왼쪽 먼저 집기. (2) 한 번에 두 포크 모두 집거나 아무것도 안 집기 (Hold & Wait 제거). (3) 철학자 수를 N-1명으로 제한 (동시 착석 제한).
프로세스 A
스레드 1
Stack · Registers · PC
스레드 2
Stack · Registers · PC
공유 영역
Code
Data
Heap
Files
프로세스 B (독립)
스레드 1 (Main)
Stack · Registers · PC
독립 메모리 공간
Code
Data
Heap
Files
⚠ 프로세스 간 직접 메모리 접근 불가 → IPC 필요
| 항목 |
프로세스 |
스레드 |
| 메모리 |
독립된 메모리 공간 |
같은 프로세스 메모리 공유 |
| 생성 비용 |
높음 (fork/exec) |
낮음 (경량) |
| 통신 방법 |
IPC (파이프, 소켓, 공유메모리) |
공유 변수 직접 접근 |
| 격리성 |
높음 (하나 죽어도 영향 없음) |
낮음 (하나 오류 → 전체 영향) |
| 컨텍스트 스위칭 |
느림 (TLB flush 등) |
빠름 (메모리 공유) |
| 동기화 |
불필요 (독립) |
필요! (Race condition 주의) |
fork() / exec() 동작
멀티스레딩: 하나의 프로세스에서 여러 스레드가 동시에 실행. CPU 코어를 최대 활용하지만 Race Condition에 주의 필요. Chrome은 탭마다 별도 프로세스(안정성↑), Node.js는 단일 스레드 + 이벤트 루프.
① Race Condition
두 스레드가 공유 변수 counter를 동시에 증가시킬 때, 예상과 다른 결과가 나올 수 있습니다.
② 뮤텍스 vs 세마포어
Mutex (상호배제)
· 값: 0 또는 1 (이진 잠금)
· 소유자가 lock/unlock
· 한 번에 1개 스레드만 진입
· 사용: 임계구역 보호
Semaphore (세마포어)
· 값: 0~N (정수 카운터)
· 여러 스레드가 사용 가능
· wait(P) / signal(V) 연산
· 사용: 자원 개수 제한
|
임계구역 (Critical Section): 공유 자원에 접근하는 코드 구간. 보호를 위해 상호배제(Mutex), 세마포어, 모니터 사용.
교착상태(Deadlock)를 피하려면 락 획득 순서를 일관되게 유지해야 합니다.