조성호 님의 "쉽게 배우는 운영체제" 책을 정리한 포스팅 입니다
1. 개요
프로그램 vs 프로세스
| 구분 | 프로그램 | 프로세스 |
| 정의 | 어떤 작업을 어떤 데이터를 사용하여 할지 절차를 적어놓은 것 | 작업이 진행되고 있는 프로그램 |
| 상태 | 정적인 상태 (저장장치에 저장됨) |
동적인 상태 (메모리에 올라와 실행 중)
|
| 저장 위치 | 디스크에 저장됨 | RAM에 적재되어 실행됨 |
| 실행 여부 | 실행되지 않음 | 실행 중인 상태 |
| 예시 | myapp.exe (실행 파일) |
myapp.exe가 실행되어 프로세스 ID를 가지고 동작하는 상태
|
프로세스 자료구조
- 프로세스를 관리하기 위한 운영체제의 데이터 구조
| 구분 | 설명 |
| PID (Process ID) |
프로세스의 고유 식별자
|
| Process state |
현재 상태 (실행, 대기, 종료 등)
|
| Process Number | 프로세스 번호 |
| Program Counter |
다음 실행할 명령어의 주소
|
| Register | CPU 레지스터 값 |
| Memory limits |
프로세스가 사용할 메모리 영역 정보 (코드, 데이터, 힙, 스택 영역 정보)
|
프로세스 상태

| 상태 | 설명 | 상황 |
| Created (New) |
프로그램이 메모리에 로드되고 PCB가 생성된 상태
|
- exec (실행 파일을 실행함)
|
| Ready (Waiting) | 실행 준비 완료, CPU 할당을 기다리는 상태 | |
| Running | CPU를 할당받아 실제 실행 중인 상태 | |
| Blocked (Waiting) |
I/O 요청 등으로 인해 CPU를 사용하지 못하고 대기 중
|
- 디스크/네트워크/입출력 요청
- 자원 획득 대기(lock) |
| Terminated | 실행이 종료되어 자원이 회수된 상태 | - 정상 종료 - 비정상 종료 - 강제 종료 |
| Suspended | 프로세스가 메모리에서 쫓겨난 상태 | - 메모리가 부족할 경우 - 프로그램 오류로 실행이 미뤄질 경우 - 바이러스 프로세스로 판단될 경우 |
| Stopped | 프로세스가 일시적으로 실행을 중단 ✅ 사용하던 데이터와 PCB 정보가 그대로 유지됨 ✅ 멈춘 지점에서 재시작 가능 |
과정) Created (New)
더보기
- 프로그램이 메모리에 로드됨
- OS로부터 PCB 할당
- 실행 준비 완료 후 Ready 상태로 전환
과정) Ready (Waiting)
더보기
- Ready Queue에서 자기 순서를 기다림
과정) Blocked (Waiting)
더보기
- I/O 요청을 수행 중
- 요청한 I/O 작업이 완료될 때까지 대기 (입출력 장치별 대기 큐에서 기다림)
상태 변화) Running
더보기
| 상태 변화 | 메서드 | 상태 |
| 실행 |
dispatch(PID)
|
새로운 프로세스가 Running 상태로 이동
|
| 할당된 time slice 만료 |
timeout(PID)
|
Ready (Waiting) 상태로 이동
|
| I/O 요청 발생 |
block(PID)
|
Blocked (Waiting) 상태로 이동
|
| 작업 완료 |
exit(PID)
|
Terminated(종료) 상태로 이동
|
상태 변화) Blocked (Waiting)
더보기
- I/O 완료 후 Ready 상태로 이동
- wakeup(PID) 호출 → Waiting(Ready) 상태로 전환
상태 변화) Terminated
더보기
| 상태 | 설명 |
| 정상 종료 | exit(0) |
| 오류로 인한 종료 | exit(n) |
| 정상 종료 요청 | kill (SIGTERM), Ctrl + C (SIGINT) |
| 강제 종료 | kill -9 (SIGKILL) |
상태 변화) Suspended
더보기
스왑 영역 (Swap Area)
- Suspended 상태의 프로세스가 저장되는 영역
- 디스크의 스왑 영역(Swap Space)에 저장됨
| 상태 | 설명 |
| 보류 대기 상태 (Swapped Out and Blocked) |
- Blocked 상태에서 스왑됨 (I/O 요청 등의 이유)
- I/O 작업이 완료되면 다시 실행 대기 |
| 보류 준비 상태 (Swapped Out and Waiting) |
- Ready 상태에서 스왑됨
- 다시 메모리로 로드되면 Ready 상태로 복귀하여 실행 대기 |
상태 변화) Stopped
더보기
- Ready or Blocked 전환됨
- ✅ Ready 상태는 명령어로 제어됨
- ✅ Blocked 상태는 i/o 요청 중 중지됨
| 상태 변경 명령어 | 설명 |
| 일시 중지 | Ctrl + Z |
| 재시작 (포그라운드) | fg |
| 재시작 (백그라운드) | bg |
Context Switching
- CPU의 실행 주체가 변경되는 과정
- 시분할 시스템에서는 여러 프로세스의 응답성과 효율성을 높이기 위해 CPU 실행 시간을 나누어 각 프로세스에 할당합니다.
- 이 과정에서 CPU는 여러 프로세스를 번갈아 가며 실행합니다.
과정) Context Switching
더보기
- 현재 프로세스의 PCB 저장: 실행 중인 프로세스의 정보를 PCB에 저장
- 새로운 프로세스의 PCB 로드: 실행할 프로세스의 PCB를 메모리에서 로드하고, 레지스터 및 PC 정보를 복원
- CPU 제어권 전달: CPU가 새로운 프로세스를 실행하도록 전환함
발생하는 상황) Context Switch
더보기
| 구분 | 설명 |
| 멀티태스킹 |
여러 프로세스를 번갈아 실행하기 위해 CPU를 교체
|
| 인터럽트 |
I/O 요청, 시스템 호출, 외부 이벤트로 인해 실행 중인 프로세스가 일시 정지됨
|
| 프로세스 우선순위 변경 |
스케줄러가 높은 우선순위의 프로세스를 실행하기 위해 전환
|
종류) Context Switching
더보기
| 구분 | 설명 |
| 프로세스 간 전환 |
두 개의 서로 다른 사용자 프로세스 간에 이루어짐
|
| 스레드 간 전환 |
동일한 프로세스 내에서 스레드 전환
|
파일 접근 구조
| 종류 | 설명 |
| FDT (File Descriptor Table) | 프로세스 오픈 파일 테이블 |
| System Open-File Table |
시스템 오픈 파일 테이블
|
| Active vnode table |
파일 시스템 캐싱 테이블 (inode 정보)
|
과정) 파일 읽기
더보기
- FDT에서 해당 파일인 fd에 해당하는 System Open-File Table 엔트리를 찾음
- inode 참조
- Active Vnode Table에서 캐싱 여부 확인
- 캐싱이 안되어있다면, System Open-File Table(disk)에서 inode 참조
- 데이터 블록 읽기
- inode를 통해 데이터 블록 접근
2. 프로세스 구조
- 프로세스가 사용하는 작업 공간
| 메모리 영역 | 설명 | 특징 |
| Text Area | 프로그램의 코드가 저장된 곳 |
|
| Data Area | 변수 및 데이터가 저장되는 영역 | - Initialized data: 초기값이 있는 변수들 - Uninitialized data (BSS): 초기값이 없는 변수들 |
| Stack Area | 함수 호출 시 생성되는 데이터를 저장하는 임시 메모리 공간 | - 스택 프레임: 지역 변수, 매개 변수, 반환 주소, 반환 값 - 함수 호출이 끝나면 해당 메모리는 자동으로 해제됨 |
| Heap Area | 런타임에 동적으로 할당되는 데이터 영역 |
- 포인터를 통해 접근 가능
- 프로그램이 종료될 때까지 메모리 해제되지 않음 - 수동 관리 필요 |
3. 프로세스 계층 구조
커널 프로세스와 init 프로세스
| 개념 | 설명 | 특징 |
| 커널 프로세스 | 커널 내부에서 동작하는 프로세스 | 시스템 자원 관리, 하드웨어 제어 |
| init 프로세스 | 커널이 부팅 완료 후 최초로 실행하는 사용자 프로세스 |
모든 사용자 프로세스의 조상 (PID 1번)
자식 프로세스를 생성함 |
프로세스 연산
| 구분 | fork() | exec() |
| 목적 | 새 프로세스 생성 | 프로세스 내용 교체 |
| PID | 자식에 새 PID | 유지 |
| 메모리 | COW 기반 복제 | 완전 교체 |
| PCB | 새로 생성 | 기존 PCB 재사용 |
| 실행 결과 | 부모 + 자식 실행 | 새 프로그램 실행 |
| 주 사용처 | 프로세스 생성 | 다른 프로그램 실행 |
코드) fork()
더보기
#include <stdio.h>
#include <unistd.h>
int main() {
int pid = fork();
if (pid > 0) {
printf("부모 프로세스\n");
} else if (pid == 0) {
printf("자식 프로세스\n");
} else {
printf("fork 실패\n");
}
return 0;
}
코드) exec()
더보기
#include <stdio.h>
#include <unistd.h>
int main() {
printf("exec 실행 전\n");
execl("/bin/ls", "ls", NULL);
printf("exec 실행 후\n"); // 실행 안 됨
return 0;
}
장점
| 장점 | 설명 |
| 동시 처리 |
여러 사용자의 요청을 처리하기 위해 fork()로 자식 프로세스를 여러 개 만들어 각 요청을 분배하기 용이함
|
| 자원 회수 용이 | 부모-자식 관계로 관리. ➡️ 종료 상태 추적 가능 |
고아 프로세스
- 부모 프로세스가 먼저 종료된 자식 프로세스
- ⚠️ 자식 프로세스의 자원이 정상적으로 반환되지 못함
- ➡️ 커널이 init 프로세스를 부모로 자동 재할당하여 자식의 자원을 회수함
좀비 프로세스
- 실행이 종료되었지만 부모 프로세스가 종료 상태를 회수하지 않아 프로세스 테이블에 남아있는 상태
- ⚠️ PID 슬롯을 차지하여 새 프로세스 생성에 영향을 줄 수 있음
- ➡️ 부모가 wait()을 호출하여 자식의 자원을 회수해야 함
5. 프로세스 실행 과정
프로세스 그룹
- 여러 프로세스를 하나의 그룹으로 묶어 터미널에서 관리하기 위한 개념
특징
| 특징 | 설명 |
| 커널의 터미널 제어 | - 터미널 제어권: 터미널은 한 번에 하나의 프로세스 그룹만 포어그라운드에서 제어함 - 하위 프로세스 실행: 같은 프로세스 그룹에 속해 있으면 같은 터미널 제어권을 공유함 |
| 프로세스 그룹 제어 |
터미널은 프로세스 그룹의 제어권을 가집니다.
즉, 어떤 프로세스가 터미널의 입력을 받거나 출력을 담당할지를 결정합니다. |
| PGID (Process Group ID) | 프로세스 그룹에는 고유한 식별자인 PGID가 부여됩니다. 같은 그룹은 터미널에서 파이프라인으로 연결되어 그룹핑됩니다. |
출처
'OS' 카테고리의 다른 글
| [쉽게 배우는 운영체제] 4-2. CPU 스케줄링: 인터럽트 처리 (0) | 2024.12.12 |
|---|---|
| [쉽게 배우는 운영체제] 4-1. CPU 스케줄링: 스케줄링 (0) | 2024.12.12 |
| [쉽게 배우는 운영체제] 3-2. 프로세스와 스레드: 스레드 (0) | 2024.12.12 |
| [쉽게 배우는 운영체제] 2. 컴퓨터의 구조와 성능 향상 (0) | 2024.01.11 |
| [쉽게 배우는 운영체제] 1. 운영체제 개요 (1) | 2023.12.26 |