운영체제가 관리하는 프로세스의 실행 상태와 자원 구조

프로세스의 메모리 구조, 상태 전이, PCB, 컨텍스트 스위칭과 IPC를 운영체제 관점에서 정리합니다.

2026-08-14 · 최초 발행 2025-12-30

디스크의 프로그램이 실행 단위가 되는 순간

프로세스(Process)는 메모리에 적재되어 CPU가 실행 중인 프로그램의 인스턴스다. 디스크에 있는 실행 파일은 정적인 프로그램이지만, 실행되면 자원을 점유하고 상태가 변하는 동적 개체가 된다. System Call 종료 시까지 전체 자원을 Blocking하며 순차적으로 실행되는 단위이기도 하다.

하나의 프로그램에서 여러 프로세스를 만들 수 있다. 예를 들어 Chrome.exe를 실행하면 여러 Chrome 프로세스가 동작할 수 있다.

실행프로그램(디스크)프로세스(메모리)Code(텍스트 영역)Data(전역 변수)Heap(동적 할당)Stack(지역 변수)CPU실행

프로세스는 CPU 시간, 메모리 공간, 파일 디스크립터, 네트워크 소켓, I/O 장치를 할당받는다. 운영체제는 이 자원을 프로세스 단위로 관리하며, 프로세스가 끝나면 해당 자원을 자동으로 회수한다.

각 프로세스는 독립적인 주소 공간을 가진다. 다른 프로세스의 메모리에 직접 접근할 수 없으며, 이 격리는 가상 메모리로 구현된다. 한 프로세스의 오류가 다른 프로세스에 영향을 주지 않도록 메모리를 보호해 시스템 안정성을 높이는 구조다.

순차 실행과 전환 비용

프로세스 안에서는 명령어가 순차적으로 실행되고 프로그램 카운터(PC)도 순차적으로 증가한다. 실행 흐름을 예측하기 쉽고, 디버깅과 실행 결과 재현에도 유리하다. 반면 I/O를 기다리는 동안에는 CPU를 활용하지 못해 동시성이 부족하고 CPU 활용률이 낮아질 수 있다.

CPU가 실행 대상을 Process A에서 Process B로 바꾸는 작업을 Context Switching이라고 한다. 이 과정에서는 현재 프로세스 상태를 PCB에 저장하고, 스케줄러가 다음 프로세스를 선택한 뒤 그 프로세스의 PCB에서 상태를 복원해 실행을 이어 간다.

Process A실행인터럽트/시간 만료상태 저장(PCB A)스케줄러선택상태 복원(PCB B)Process B실행ContextSwitching오버헤드

전환 과정에서는 레지스터 저장과 복원, 캐시 무효화, TLB 플러시가 발생하며 수 마이크로초 ~ 수십 마이크로초의 오버헤드가 든다. 타임 슬라이스가 만료되거나 I/O 요청으로 Blocking될 때, 인터럽트가 발생했을 때, 우선순위가 높은 프로세스가 Ready 상태가 될 때 전환이 일어날 수 있다.

스케줄러가 다루는 프로세스 상태

Ready 상태는 실행 준비를 마쳤지만 CPU 할당을 기다리는 상태다. 프로세스는 Ready Queue에서 대기하며, 생성이 완료되면 New에서 Ready로 이동한다. 실행 중 타임 슬라이스가 만료되거나 선점되면 Run에서 Ready로 되돌아간다.

Run 상태에서는 CPU를 할당받아 명령어를 수행한다. 단일 CPU 시스템에서는 한 번에 하나의 프로세스만 Run 상태가 될 수 있다. 스케줄러의 Dispatch로 Ready에서 Run으로 전환하며, 선점되면 Ready로, I/O 요청이나 대기가 필요하면 Sleep으로, 실행을 마치면 Terminated로 이동한다.

Sleep 상태는 I/O 완료나 이벤트를 기다리므로 CPU가 할당되어도 실행할 수 없는 상태다. Wait Queue에서 대기하다가 I/O가 완료되거나 이벤트가 발생하면 Ready 상태로 돌아간다. 디스크 읽기, 네트워크 패킷 수신, 자식 프로세스 종료를 기다리는 wait가 여기에 해당한다.

DispatchTimeoutI/O 요청I/O 완료New(생성)Ready(준비)Run(실행)Sleep(대기)Terminated(종료)

프로세스 상태는 New, Ready, Run, Sleep (Wait), Terminated (Exit)의 5-State 모델로 볼 수 있다.

주소 공간과 PCB에 담기는 정보

프로세스의 메모리는 Code, Data, Heap, Stack 영역으로 나뉜다. Code(Text) 영역에는 기계어 실행 코드가 있으며 읽기 전용이고, 동일 프로그램의 다중 프로세스가 공유할 수 있다. Data 영역은 전역 변수와 static 변수를 담고, 초기화된 데이터는 .data, 초기화되지 않은 데이터는 .bss에 위치한다.

Heap은 malloc, new 같은 동적 메모리 할당에 사용되며 낮은 주소에서 높은 주소 방향으로 성장하고 런타임에 크기가 바뀐다. Stack에는 지역 변수, 함수 매개변수, Return Address 같은 함수 호출 정보가 저장된다. Stack은 높은 주소에서 낮은 주소 방향으로 성장하며 LIFO(Last In First Out) 방식으로 동작한다.

성장성장프로세스메모리Stack(지역 변수)Heap(동적 할당)Data(전역 변수)Code(실행 코드)

PCB(Process Control Block)는 운영체제가 프로세스를 관리하기 위해 쓰는 자료구조다. Linux에서는 task_struct, Windows에서는 EPROCESS가 이 역할을 한다. PCB에는 프로세스 상태, 다음 명령어 주소를 가리키는 프로그램 카운터(PC), CPU 레지스터 값, PID와 PPID, 스케줄링 우선순위가 들어간다. 페이지 테이블과 세그먼트 테이블 같은 메모리 정보, 파일 디스크립터 테이블, 사용한 CPU 시간도 관리 대상이다.

이 정보는 Context Switching 시 상태를 저장하고 복원하는 데 쓰이며, 스케줄링과 프로세스 관리의 기반이 된다.

생성된 프로세스가 종료될 때까지

fork() System Call은 부모 프로세스를 바탕으로 자식 프로세스를 생성한다.

pid_t pid = fork();

if (pid == 0) {
    // 자식 프로세스
    printf("Child PID: %d\n", getpid());
} else if (pid > 0) {
    // 부모 프로세스
    printf("Parent PID: %d, Child PID: %d\n", getpid(), pid);
}

생성 시에는 부모 프로세스의 PCB를 복사하고 새 PID를 할당한다. 메모리는 Copy-On-Write 방식으로 복사되며, 자식 프로세스는 Ready 상태가 된다.

execve() System Call은 현재 프로세스 이미지를 새 프로그램으로 교체한다. 일반적으로 fork() 뒤에 execve()를 호출한다.

execve("/bin/ls", argv, envp);

정상 종료에는 exit(0)를 사용할 수 있다.

exit(0);  // 종료 코드 0 (성공)

Segmentation Fault, Abort, kill 시그널에 따른 강제 종료는 비정상 종료에 해당한다. 종료 과정에서는 모든 자원을 해제하고 열린 파일을 닫으며 메모리를 반환한다. 이후 부모 프로세스에 종료 상태를 전달하고, 부모가 wait를 호출할 때까지 Zombie 상태로 남는다.

분리된 프로세스가 협업하는 방법

독립적인 메모리 공간 때문에 프로세스는 직접 데이터를 공유할 수 없다. 데이터 공유와 협력 작업에는 IPC(Inter-Process Communication)가 필요하다.

파이프(Pipe)는 단방향 통신에 쓰이고, 메시지 큐(Message Queue)는 메시지 기반 통신을 제공한다. 공유 메모리(Shared Memory)는 가장 빠르며, 소켓(Socket)은 네트워크 통신에 사용한다. 시그널(Signal)은 비동기 이벤트를 알리는 수단이다.

PipeMessage QueueShared MemorySocketSignalProcess AProcess B

쓰레드와 비교할 때 달라지는 경계

구분 프로세스 쓰레드
정의 실행 중인 프로그램 프로세스 내 실행 흐름
메모리 독립적 공유 (Code, Data, Heap)
자원 할당 프로세스 단위 쓰레드는 최소한 자원
Context Switch 오버헤드 큼 오버헤드 작음
통신 IPC 필요 직접 메모리 접근 가능
생성 비용 높음 낮음
안정성 높음 (격리) 낮음 (공유로 인한 충돌)

프로세스는 자원 할당의 기본 단위로 독립적인 메모리 공간을 제공한다. 그 격리는 안정성을 높이지만, 프로세스 사이의 통신에는 IPC가 필요하고 Context Switching 비용도 쓰레드보다 크다.

프로세스운영체제PCBIPC컨텍스트 스위칭