운영체제, 프로세스와 스레드
커널·시스템콜, 프로세스 상태와 PCB, 스레드·문맥교환·IPC를 학습한다.
1. 운영체제의 역할
운영체제는 CPU, 메모리, 파일, 입출력 장치 같은 자원을 관리하고 사용자와 응용프로그램에 실행 환경을 제공한다.
- 처리량 향상
- 응답·반환시간 단축
- 자원 이용률과 가용성 향상
- 보호·보안과 오류 처리
커널은 운영체제의 핵심이며 사용자 모드 프로그램은 시스템콜을 통해 커널 서비스를 요청한다. 시스템콜이 발생하면 CPU는 커널 모드로 전환해 파일 열기, 프로세스 생성, 메모리 할당 같은 작업을 수행한다.
2. 프로그램, 프로세스, 스레드
- 프로그램: 저장장치에 있는 정적인 명령 집합
- 프로세스: 실행 중인 프로그램의 인스턴스
- 스레드: 프로세스 안에서 CPU 스케줄링의 기본 실행 흐름
같은 프로세스의 스레드들은 코드·데이터·힙·열린 파일을 공유하지만, 각자 프로그램 카운터·레지스터·스택을 가진다.
| 항목 | 프로세스 | 스레드 |
|---|---|---|
| 주소공간 | 일반적으로 독립 | 같은 프로세스 안에서 공유 |
| 생성·전환 비용 | 비교적 큼 | 비교적 작음 |
| 오류 영향 | 다른 프로세스와 격리 | 한 스레드 오류가 프로세스 전체에 영향 가능 |
| 통신 | IPC 필요 | 공유 메모리로 직접 통신 가능 |
3. 프로세스 상태와 PCB
대표 상태는 생성, 준비, 실행, 대기(봉쇄), 종료이다.
- 준비 → 실행: 디스패치
- 실행 → 준비: 시간 할당량 종료·선점
- 실행 → 대기: 입출력·이벤트 대기
- 대기 → 준비: 입출력·이벤트 완료
PCB(Process Control Block)는 프로세스 식별자, 상태, 프로그램 카운터, 레지스터, 스케줄링 정보, 메모리 정보, 열린 파일·입출력 상태 등을 저장한다.
4. 문맥교환
실행 중인 프로세스 또는 스레드를 바꿀 때 현재 실행 상태를 PCB 등에 저장하고 다음 실행 대상의 상태를 복원한다. 문맥교환 동안 실제 사용자 작업이 진행되지 않으므로 지나치게 잦으면 오버헤드가 증가한다.
5. 프로세스 간 통신(IPC)
- 파이프: 관련 프로세스 사이의 바이트 흐름
- 메시지 큐: 메시지 단위 비동기 통신
- 공유 메모리: 빠르지만 동기화 필요
- 소켓: 같은 호스트 또는 네트워크의 프로세스 통신
- 시그널: 이벤트 통지
6. 스레드 모델
사용자 수준 스레드는 라이브러리가 관리해 빠르지만 커널이 개별 스레드를 모를 수 있다. 커널 수준 스레드는 운영체제가 직접 스케줄링하므로 병렬 실행과 봉쇄 처리가 유리하지만 관리 비용이 크다.
7. 프로세스 주소공간과 실행 이미지
프로세스의 가상주소공간은 전형적으로 다음처럼 나뉜다. 실제 배치 방향과 세부 영역은 운영체제·ABI에 따라 달라질 수 있다.
높은 주소
┌──────────────────────┐
│ 커널 영역(보호됨) │
├──────────────────────┤
│ 스택 ↓ │ 함수 호출 프레임, 지역변수
│ 빈 가상공간 │
│ 힙 ↑ │ 동적 할당
├──────────────────────┤
│ BSS │ 0으로 초기화되는 전역·정적 변수
│ Data │ 초기값이 있는 전역·정적 변수
│ Text/Code │ 기계어, 보통 읽기 전용
└──────────────────────┘
낮은 주소
같은 실행 파일에서 시작한 프로세스라도 주소공간은 원칙적으로 독립적이다. fork() 계열은 부모의 주소공간을 논리적으로 복제하며, 실제로는 copy-on-write를 이용해 수정 전까지 물리 페이지를 공유할 수 있다. exec() 계열은 현재 프로세스의 실행 이미지를 새 프로그램으로 교체하지만 프로세스 식별자 자체는 유지될 수 있다.
8. 상태 전이와 CPU·I/O 버스트
dispatch
준비 ─────────────→ 실행 ─────→ 종료
↑ │ │
│ I/O 완료 │ └─ I/O 요청/이벤트 대기
│ ↓
└──────────────── 대기
선점/시간 만료: 실행 → 준비
CPU 중심 프로세스는 긴 CPU 버스트를, I/O 중심 프로세스는 짧은 CPU 버스트와 잦은 I/O 대기를 보이는 경향이 있다. 스케줄러는 이 특성에 따라 응답성과 처리량의 균형을 잡는다. 일부 운영체제 모델은 메모리에서 내려간 준비 중지·대기 중지 상태도 둔다.
9. 문맥교환과 모드 전환의 차이
- 모드 전환: 같은 프로세스가 시스템콜·예외로 사용자 모드에서 커널 모드로 바뀔 수 있다.
- 문맥교환: 실행 주체가 바뀌므로 레지스터, PC, 스택 포인터, 주소공간 관련 정보 등을 저장·복원한다.
따라서 시스템콜이 발생했다고 항상 다른 프로세스로 문맥교환되는 것은 아니다. 반대로 타이머 인터럽트 후 스케줄러가 다른 프로세스를 선택하면 모드 전환과 문맥교환이 연달아 일어날 수 있다.
10. 동시성과 병렬성, 스레드 안전성
동시성(concurrency): 여러 작업의 진행 구간이 시간상 겹침
병렬성(parallelism): 여러 코어에서 같은 시점에 실제 실행
단일 코어도 빠른 전환으로 동시성을 제공할 수 있지만 물리적 병렬 실행은 다중 코어가 필요하다. 같은 프로세스의 스레드는 힙과 전역 데이터를 공유하므로 통신은 빠르지만 경쟁상태가 발생할 수 있다. 함수가 공유 상태 없이 재진입 가능하거나 적절한 동기화를 사용해야 thread-safe하다고 할 수 있다.
11. 사용자 스레드와 커널 스레드 매핑
| 모델 | 특징 | 대표 영향 |
|---|---|---|
| many-to-one | 여러 사용자 스레드가 한 커널 스레드에 매핑 | 한 봉쇄 호출이 전체를 막을 수 있고 다중 코어 병렬성 제한 |
| one-to-one | 사용자 스레드마다 커널 스레드 | 병렬성·봉쇄 독립성 우수, 생성·관리 비용 증가 |
| many-to-many | 여러 사용자 스레드를 여러 커널 스레드에 다중화 | 유연하지만 구현 복잡 |
12. IPC 선택과 데이터 전달
| 방식 | 복사·공유 특성 | 동기화·경계 | 적합한 상황 |
|---|---|---|---|
| 파이프 | 커널 버퍼를 통한 바이트 흐름 | 보통 단방향, 관련 프로세스 | 단순 스트림 연결 |
| 메시지 큐 | 메시지 경계를 보존 | 커널이 큐 관리 | 비동기 작업 전달 |
| 공유 메모리 | 같은 물리 메모리 영역 매핑 | 별도 락·세마포어 필요 | 대용량·고속 통신 |
| 소켓 | 로컬·네트워크 통신 | 프로토콜·직렬화 비용 | 분산 프로세스 |
| 시그널 | 작은 사건 통지 | 전달 정보가 제한적 | 종료·상태 변화 알림 |
공유 메모리가 데이터 복사를 줄여 빠르더라도 일관성과 동기화 비용이 사라지는 것은 아니다.
13. 프로세스 종료와 자원 회수
자식이 종료했지만 부모가 종료 상태를 회수하지 않으면 좀비 프로세스로 남을 수 있다. 부모가 먼저 종료한 자식은 고아 프로세스가 되어 시스템의 지정 프로세스가 인계한다. 좀비는 실행 중인 프로세스가 아니라 종료 상태와 식별 정보만 남은 상태라는 점을 구분한다.
최종 확인 문제
- 같은 프로세스의 두 스레드가 일반적으로 공유하는 영역 세 가지와 각자 가지는 상태 세 가지를 쓰시오.
- 시스템콜이 발생했지만 스케줄러가 다른 프로세스를 선택하지 않았다. 이것을 반드시 문맥교환이라고 할 수 있는가?
fork()후 부모와 자식이 수정 전까지 같은 물리 페이지를 공유하다가 쓰기 시 복사하는 기법을 무엇이라 하는가?- many-to-one 스레드 모델에서 한 사용자 스레드의 봉쇄 시스템콜이 전체 스레드 진행을 막을 수 있는 이유를 설명하시오.
- 프로세스가 종료했지만 부모가 종료 상태를 회수하지 않은 상태를 무엇이라 하는가?