운영체제 프로세스·스레드 핵심정리
프로세스 상태, 문맥교환, 스케줄링, 교착상태를 한 흐름으로 연결해 정리합니다.
프로세스와 스레드
프로세스는 독립된 주소 공간과 자원을 가진 실행 단위이고, 스레드는 프로세스 안에서 코드·데이터·힙을 공유하면서 스택과 레지스터를 따로 갖는 실행 흐름입니다.
- 스레드 전환은 일반적으로 프로세스 전환보다 가볍다.
- 공유 메모리는 빠르지만 동기화 문제가 생긴다.
- PCB는 프로세스 상태와 문맥 정보를 보관한다.
스케줄링 판단
선점형은 실행 중인 프로세스의 CPU를 회수할 수 있고, 비선점형은 자발적 반납이나 종료까지 기다립니다. 평균 대기시간 계산에서는 도착시간과 실행 순서를 먼저 시간축에 표시해야 합니다.
- RR은 시간 할당량이 지나면 준비 큐 뒤로 이동한다.
- SJF는 평균 대기시간에 유리하지만 긴 작업의 기아가 가능하다.
- 다단계 피드백 큐는 행동에 따라 큐 사이를 이동한다.
교착상태
상호배제·점유대기·비선점·환형대기의 네 조건이 동시에 성립할 때 교착상태가 가능합니다. 예방은 조건 하나를 깨고, 회피는 안전상태를 유지하며, 탐지는 발생 후 찾아 복구합니다.
- 은행원 알고리즘은 회피 기법이다.
- 자원 할당 그래프에서 각 자원 유형의 인스턴스가 하나뿐이면 사이클은 교착상태를 뜻한다. 여러 인스턴스가 있는 경우에는 사이클만으로 교착상태를 확정할 수 없다.
- 기아는 무기한 대기이고 교착상태와 원인이 다르다.
상태 전이와 계산 문제를 함께 푸는 법
프로세스 문제는 준비·실행·대기 상태를 먼저 구분한 뒤 어떤 사건이 전이를 일으켰는지 추적해야 합니다. 스케줄링 계산에서는 도착시간, CPU 사용시간, 선점 시점과 시간 할당량을 시간축에 적고 대기시간·반환시간·응답시간을 각각 계산하면 용어 혼동을 줄일 수 있습니다.
- I/O 요청은 실행에서 대기로, I/O 완료는 대기에서 준비로 이동한다.
- 반환시간은 완료시간−도착시간이다. I/O와 다른 중단 시간이 없는 CPU 스케줄링 예제에서는 대기시간=반환시간−CPU 실행시간이다. I/O가 있으면 준비 큐에서 기다린 시간만 별도로 합산한다.
- 공유 자원 문제가 나오면 임계구역·상호배제·진행·한정대기 조건을 함께 확인한다.
동기화·메모리 관리까지 연결하기
프로세스와 스레드 문제는 실행 순서뿐 아니라 공유 데이터 보호와 메모리 배치까지 연결됩니다. 임계구역에서는 상호배제를 보장하되 진행과 한정대기 조건을 만족해야 하며, 가상메모리에서는 페이지 부재와 교체 횟수를 참조열 순서대로 계산해야 합니다.
- 뮤텍스는 소유권을 전제로 한 상호배제, 세마포어는 정수값으로 사용 가능한 자원 수를 표현할 수 있다.
- LRU는 가장 오래 참조되지 않은 페이지를, FIFO는 가장 먼저 들어온 페이지를 교체한다.
- Belady의 모순은 프레임을 늘려도 FIFO의 페이지 부재가 증가할 수 있는 현상이다.
- 공유 메모리는 빠르지만 별도 동기화가 필요하고 메시지 전달은 주소 공간을 직접 공유하지 않는다.
파일 시스템·입출력·보호 영역 마무리
파일 시스템은 파일의 논리 구조와 디스크 블록 배치, 디렉터리 탐색, 빈 공간 관리를 함께 봐야 합니다. 입출력은 CPU가 장치를 직접 확인하는 프로그램 I/O, 완료를 알리는 인터럽트, 블록 전송을 맡기는 DMA를 구분하고 사용자 모드와 커널 모드의 보호 경계를 연결합니다.
- 연속 할당은 순차·직접 접근이 빠르지만 외부 단편화와 파일 확장 문제가 있고, 연결 할당은 순차 접근에 적합하지만 직접 접근이 불리하다.
- 인덱스 할당은 인덱스 블록으로 파일 블록 위치를 관리하며 작은 파일에도 인덱스 공간이 필요하다.
- 버퍼링은 속도 차이를 완화하고 스풀링은 디스크를 중간 저장소로 이용해 장치를 여러 작업이 공유하게 한다.
- 시스템 호출은 사용자 프로그램이 커널 기능을 요청하는 통제된 진입점이며 인터럽트·예외와 발생 원인을 구분한다.
시험에 바로 쓰는 비교표
| 구분 | CPU 회수 | 대표 방식 | 출제 함정 |
|---|---|---|---|
| 선점형 | 실행 중 회수 가능 | RR, SRT, 선점 우선순위 | 응답성은 좋지만 문맥교환 비용 증가 |
| 비선점형 | 종료·대기 전환까지 유지 | FCFS, SJF, HRN | 짧은 작업이 늦게 도착해도 즉시 끼어들 수 없음 |
| 교착상태 회피 | 안전상태를 유지 | 은행원 알고리즘 | 예방처럼 필요조건을 반드시 제거하는 방식이 아님 |
지문 표현을 판단 기준으로 바꾸기
- 시간 할당량이 지나 준비 큐의 뒤로 이동한다 → RR
- 시스템이 안전상태를 유지하도록 자원을 배분한다 → 회피
- 최근 사용한 페이지가 다시 쓰일 가능성 → 시간 지역성
직접 풀어보는 예제와 단계별 해설
CPU 스케줄링은 도착 순서와 선점 시점을, 자원 할당은 현재 여유와 앞으로의 최대 요구량을 나누어 추적합니다. 첫 스케줄링 예제는 I/O 없이 CPU만 사용하고 문맥 교환 비용은 0으로 둡니다.
도착 시각이 다른 프로세스의 라운드 로빈 추적
시간 할당량은 2입니다. 할당량이 끝나는 순간 도착한 프로세스를 먼저 준비 큐에 넣고, 실행을 마치지 못한 프로세스는 그 뒤에 넣습니다.
넓은 표는 좌우로 밀어 나머지 열을 볼 수 있습니다.
| 프로세스 | 도착 시각 | CPU 실행시간 |
|---|---|---|
| A | 0 | 5 |
| B | 1 | 3 |
| C | 2 | 1 |
| 구간 | CPU | 구간 종료 뒤 준비 큐 |
|---|---|---|
| 0–2 | A (잔여 3) | B, C, A |
| 2–4 | B (잔여 1) | C, A, B |
| 4–5 | C (종료) | A, B |
| 5–7 | A (잔여 1) | B, A |
| 7–8 | B (종료) | A |
| 8–9 | A (종료) | 없음 |
| 프로세스 | 완료 | 반환 = 완료 − 도착 | 대기 = 반환 − CPU | 응답 = 첫 실행 − 도착 |
|---|---|---|---|---|
| A | 9 | 9 | 4 | 0 |
| B | 8 | 7 | 4 | 1 |
| C | 5 | 3 | 2 | 2 |
풀이 순서
- A가 첫 할당량을 쓴 동안 B와 C가 도착하므로 다음 순서는 B, C, A입니다. 이후에는 매 구간의 잔여 실행시간을 빼면서 큐 맨 뒤로 보냅니다.
- 평균 대기시간은 (4 + 4 + 2) / 3 = 약 3.33, 평균 반환시간은 (9 + 7 + 3) / 3 = 약 6.33입니다.
- 같은 입력의 FCFS는 A 0–5, B 5–8, C 8–9입니다. 평균 대기시간은 똑같이 약 3.33이지만 C의 응답시간은 6으로 늘어납니다. 하나의 평균만으로 스케줄러의 모든 특성을 비교할 수 없습니다.
틀리기 쉬운 지점: 대기시간과 응답시간은 다릅니다. 선점되어 여러 번 기다린 시간은 대기시간에 누적되지만 응답시간은 첫 실행까지만 셉니다.
자원이 남아 있는데도 은행원 알고리즘이 요청을 보류하는 이유
동일한 자원 6개가 있고 P1·P2·P3의 현재 할당은 [1, 2, 1], 최대 동시 요구량은 [4, 4, 3]입니다. 남은 자원은 2개이며, 프로세스는 필요한 자원을 받으면 유한 시간 안에 종료하여 할당받은 자원을 모두 반환한다고 가정합니다. 현재 상태가 안전한지 확인하고 P1의 1개 추가 요청을 허용할지 판단하세요. Max는 매번 반드시 요구할 수량이 아니라 미리 선언한 상한입니다.
Python 3
def safe_sequence(allocation, maximum, available):
work = available
finished = [False] * len(allocation)
sequence = []
while len(sequence) < len(allocation):
for index in range(len(allocation)):
need = maximum[index] - allocation[index]
if not finished[index] and need <= work:
work += allocation[index]
finished[index] = True
sequence.append(f'P{index + 1}')
break # 한 개를 선택하면 P1부터 다시 검사합니다.
else:
return None
return sequence
allocation = [1, 2, 1]
maximum = [4, 4, 3]
available = 2
cases = [
('before', allocation, available),
('P1+1', [2, 2, 1], available - 1),
('P2+1', [1, 3, 1], available - 1),
]
for label, tentative, remaining in cases:
sequence = safe_sequence(tentative, maximum, remaining)
result = 'UNSAFE' if sequence is None else ' -> '.join(sequence)
print(label, result)넓은 표는 좌우로 밀어 나머지 열을 볼 수 있습니다.
| 프로세스 | Allocation | Max | Need = Max − Allocation |
|---|---|---|---|
| P1 | 1 | 4 | 3 |
| P2 | 2 | 4 | 2 |
| P3 | 1 | 3 | 2 |
| 선택 | 선택 전 Work | Need ≤ Work | 완료 뒤 Work |
|---|---|---|---|
| P2 | 2 | 2 ≤ 2 | 2 + 2 = 4 |
| P1 | 4 | 3 ≤ 4 | 4 + 1 = 5 |
| P3 | 5 | 2 ≤ 5 | 5 + 1 = 6 |
| 상태 | 잠정 Allocation | 잠정 Available / Need | 판정 |
|---|---|---|---|
| 요청 전 | [1, 2, 1] | 2 / [3, 2, 2] | 안전 |
| P1에 1개 추가 | [2, 2, 1] | 1 / [2, 2, 2] | 불안전 → 요청 보류 |
| P2에 1개 추가 | [1, 3, 1] | 1 / [3, 1, 2] | 안전 → 요청 허용 가능 |
풀이 순서
- 처음에는 P1의 Need 3을 채우지 못하지만 P2의 Need 2는 Work 2로 충족할 수 있습니다. P2가 종료했다고 가정하면 Work는 4가 되어 P1, P3도 순서대로 완료할 수 있습니다. 코드는 선택할 때마다 P1부터 다시 검사하므로 P2 → P1 → P3을 출력하며, 안전 순서가 이것 하나뿐이라는 뜻은 아닙니다.
- Work에는 Need를 더하지 않습니다. 남은 요구량을 잠시 지급했다가 완료 시 돌려받으므로 순변화는 원래 할당량만큼입니다. P2의 경우 2 − 2 + (2 + 2) = 4로, Work + Allocation과 같습니다. 이 검사는 실제 프로세스를 종료하는 실행이 아니라 완료 가능성의 모의 계산입니다.
- P1의 요청 1은 Need 3 이하이고 Available 2 이하입니다. 그러나 잠정 할당 뒤 Work는 1, 모든 Need는 2이므로 첫 번째로 완료시킬 프로세스를 찾을 수 없습니다. 두 수량 검사만으로 허용하지 않고 안전성 검사에서 보류합니다. 실제 상태는 요청 전 상태로 유지해야 합니다.
- 불안전하다는 결과만으로 지금 교착상태라고 단정할 수 없습니다. 현재 대기 요청은 제시되지 않았고 프로세스가 선언한 최대량을 다 쓰지 않고 끝날 수도 있습니다. 불안전은 최대 요구까지 고려했을 때 모두의 완료를 보장할 순서가 없다는 뜻입니다.
- 다시 풀기: 같은 처음 상태에서 P2만 1개 더 요청하면 남은 Need는 [3, 1, 2], Work는 1입니다. P2가 먼저 완료하면 Work는 1 + 3 = 4가 되어 P1과 P3도 끝납니다. 같은 1개 요청이라도 요청한 프로세스에 따라 허용 여부가 달라집니다.
확인 결과
before P2 -> P1 -> P3
P1+1 UNSAFE
P2+1 P2 -> P1 -> P3틀리기 쉬운 지점: 안전성 알고리즘은 유효한 할당·최대량·여유량을 입력받는 부분입니다. 실제 요청 처리에서는 Request ≤ Need, Request ≤ Available을 먼저 확인하고, 복사한 잠정 상태의 안전성까지 확인해야 합니다. 안전 순서는 CPU 스케줄링 순서나 실제 종료 시각의 예측이 아닙니다.
검증 방법과 참고 문서
명시한 큐 처리 규칙으로 시뮬레이션한 시간축, 완료 시각과 계산표를 테스트합니다. 자원 할당은 공개 Python 코드와 별도로 모든 완료 순서를 열거하여 세 상태의 안전성·자원 총량·입력 보존을 대조합니다. 실제 운영체제에서 자원을 할당하거나 교착상태를 일으킨 실험이 아닙니다.
예제·데이터·풀이표: 정처LAB 자체 설계 · AI 보조 작성 및 로컬 검증 · 예제 수정일 2026-10-16
혼동하기 쉬운 지점
- 스레드가 모든 메모리를 독립적으로 가진다고 판단
- 교착상태의 필요조건 하나만 성립해도 발생한다고 판단
- 응답시간과 반환시간을 혼동
개념을 확인했다면 관련 문제에 적용해보세요.
첫 관련 문제 풀기