2026년 5월 7일
CS / Theory / OS[OS] 프로그램과 프로세스
프로세스는 운영체제에서 가장 핵심적인 개념 중 하나다. CPU 스케줄링, 메모리 관리, 시스템콜 모두 프로세스를 기반으로 동작한다. 이 글에서는 프로그램이 프로세스가 되는 과정부터, 프로세스의 구조와 동작 방식까지 순서대로 살펴본다.
목차
[1] 프로그램과 프로세스
[2] 프로세스 메모리 구조
[3] 프로그램이 실행되는 과정
[4] CPU 관점의 실행
전체 흐름 정리
[1] 프로그램과 프로세스
프로그램이란
프로그램은 하드디스크나 SSD 같은 저장장치에 저장된 실행 파일이다. 아직 실행되지 않은, 수동적인 존재다.
예를 들어 chrome.exe, python.exe 같은 파일이 여기에 해당한다. 파일 탐색기에서 아이콘을 클릭하기 전까지는 그냥 저장장치 위의 데이터일 뿐이다.
프로세스
프로세스는 프로그램이 메모리에 올라와 실행 중인 상태다. CPU를 사용하고, 메모리를 차지하며, 운영체제의 관리를 받는 능동적인 존재다.
같은 프로그램도 여러 번 실행하면 여러 개의 프로세스가 된다. 크롬 탭을 여러 개 열면 각각 별도의 프로세스로 동작하는 것이 그 예다.
| 구분 | 프로그램 | 프로세스 |
|---|---|---|
| 상태 | 저장장치에 저장된 파일 | 메모리에 올라와 실행 중인 상태 |
| 존재 방식 | 수동적 | 능동적 |
| OS 관리 | X | O |
프로그램이 프로세스가 되는 과정
- 사용자가 저장장치에 있는 실행 파일을 실행한다.
- 운영체제가 해당 프로그램을 메모리에 적재한다.
- 메모리에 올라가 실행되면 프로세스가 된다.
[2] 프로세스 메모리 구조
프로세스가 메모리에 올라올 때, 메모리 공간은 네 가지 영역으로 나뉜다.
높은 주소
┌──────────────┐
│ 스택 영역 │ ← 지역 변수, 함수 호출 정보
├──────────────┤
│ (빈 공간) │
│ │
├──────────────┤
│ 힙 영역 │ ← 동적 메모리 할당
├──────────────┤
│ 데이터 영역 │ ← 전역 변수, static 변수
├──────────────┤
│ 코드 영역 │ ← 실행할 명령어
└──────────────┘
낮은 주소코드 영역 (Code / Text) — 실행할 명령어가 저장되는 공간이다. CPU는 이 영역에서 명령어를 하나씩 읽어 실행한다. 프로그램이 실행되는 동안 내용이 바뀌지 않는다.
데이터 영역 (Data) — 전역 변수와 static 변수가 저장되는 공간이다. 프로그램이 시작될 때 할당되고, 종료될 때 해제된다.
힙 영역 (Heap) — 실행 중에 동적으로 할당되는 메모리 공간이다. C에서 malloc()으로 할당하고 free()로 해제하는 메모리가 여기에 해당한다. 개발자가 직접 관리해야 하며, 해제하지 않으면 메모리 누수(Memory Leak) 가 발생한다.
스택 영역 (Stack) — 함수 호출 시 생성되는 지역 변수와 복귀 주소가 저장되는 공간이다. 함수가 호출될 때 스택 프레임이 쌓이고, 함수가 끝나면 자동으로 해제된다. 재귀 호출이 너무 깊어지면 스택 공간이 넘쳐 스택 오버플로우(Stack Overflow) 가 발생한다.
[3] 프로그램이 실행되는 과정
test.c 같은 소스 코드가 실행 파일이 되기까지는 네 단계를 거친다.
1단계 — 전처리 (Preprocessing)
#include, #define 같은 전처리 지시문을 처리한다. 헤더 파일을 포함시키고, 매크로를 치환한다.
- 입력:
test.c - 출력:
test.i
2단계 — 컴파일 (Compile)
C 언어 코드를 어셈블리어로 변환한다. 이 단계에서 문법 오류가 발견되면 컴파일이 중단된다.
- 입력:
test.i - 출력:
test.s
3단계 — 어셈블 (Assemble)
어셈블리어를 CPU가 이해할 수 있는 **기계어(0과 1)**로 변환한다.
- 입력:
test.s - 출력:
test.o(오브젝트 파일)
4단계 — 링킹 (Linking)
외부 라이브러리와 여러 오브젝트 파일을 하나로 묶어 최종 실행 파일을 만든다.
- 입력:
test.o+ 라이브러리 - 출력:
test.exe(또는 Linux에서는a.out)
test.c
↓ 전처리
test.i
↓ 컴파일
test.s
↓ 어셈블
test.o
↓ 링킹
test.exe → 실행 → 메모리 적재 → 프로세스[4] CPU 관점의 실행
실행 파일이 메모리에 올라오면, CPU는 코드 영역에서 명령어를 하나씩 읽어 실행한다. 이 과정에 관여하는 CPU 내부 구성 요소는 다음과 같다.
제어장치 (Control Unit) — 메모리에서 명령어를 가져오고 해석한다. 다른 구성 요소에 어떤 동작을 할지 지시한다.
레지스터 (Register) — CPU 내부의 초고속 임시 저장 공간이다. 현재 처리 중인 값이나 다음에 실행할 명령어 주소를 담아둔다.
- 프로그램 카운터(PC): 다음에 실행할 명령어의 주소를 가리킨다.
- 누산기(Accumulator): 연산 결과를 임시로 저장한다.
ALU (산술논리연산장치) — 실제 연산을 수행하는 부품이다. 덧셈, 뺄셈 같은 산술 연산과 AND, OR 같은 논리 연산을 처리한다.
명령어 하나가 처리되는 흐름은 다음과 같다.
1. Fetch — 제어장치가 메모리에서 명령어를 가져온다.
2. Decode — 명령어를 해석한다.
3. Execute — ALU가 연산을 수행한다.
4. Write — 결과를 레지스터 또는 메모리에 저장한다.
이 사이클이 프로그램이 종료될 때까지 반복된다.
전체 흐름 정리
저장장치의 실행 파일 (프로그램)
↓ 실행
운영체제가 메모리에 적재
↓
프로세스 생성 (코드 / 데이터 / 힙 / 스택 영역 구성)
↓
CPU가 코드 영역에서 명령어를 읽어 실행
Fetch → Decode → Execute → Write → 반복
↓
프로세스 종료 → 메모리 해제프로그램과 프로세스의 차이를 이해하는 것은 OS를 공부하는 출발점이다. 이후에 다룰 PCB, 프로세스 상태, 컨텍스트 스위칭, 스레드 모두 이 개념 위에서 설명된다.
다음 글에서는 운영체제가 여러 프로세스를 동시에 실행하는 방법인 멀티프로그래밍과 멀티프로세싱을 살펴볼 예정이다.
댓글
댓글을 불러오는 중...