프로세스

운영체제로부터 자원을 할당받아 실행 중인 프로그램의 인스턴스입니다.

프로그램 vs 프로세스

[ 프로그램 ]                        [ 프로세스 ]
디스크에 저장된 실행 파일              메모리에 올라가 실행 중인 상태
정적, 생명 없음                      동적, 생명주기 있음

app.exe (디스크)
   │  더블클릭 (실행)
   ▼
┌─── 프로세스 (PID: 1234) ───┐
│  메모리 할당                 │
│  CPU 시간 할당               │
│  파일 핸들, 소켓 등 자원      │
└─────────────────────────────┘
비유:
프로그램 = 요리 레시피 (종이에 적힌 것)
프로세스 = 실제로 요리하고 있는 행위 (재료, 불, 도구 사용 중)

같은 레시피로 동시에 두 요리 가능 = 같은 프로그램으로 프로세스 여러 개 생성 가능

프로세스의 메모리 구조

┌─────────── 프로세스 메모리 ───────────┐
│                                       │
│  ┌─── Stack ───┐     높은 주소       │
│  │ 지역 변수     │        ↓           │
│  │ 매개변수      │                    │
│  │ 리턴 주소     │                    │
│  └──────────────┘                    │
│         ↓ 증가                        │
│                                       │
│         ↑ 증가                        │
│  ┌─── Heap ────┐                     │
│  │ 동적 할당     │                    │
│  │ (malloc, new)│                    │
│  └──────────────┘                    │
│                                       │
│  ┌─── Data ────┐                     │
│  │ 전역 변수     │                    │
│  │ static 변수   │                    │
│  └──────────────┘                    │
│                                       │
│  ┌─── Code(Text) ┐    낮은 주소      │
│  │ 실행할 명령어    │                  │
│  │ (기계어 코드)    │                  │
│  └────────────────┘                  │
└───────────────────────────────────────┘
영역저장 내용특징
Code (Text)실행할 기계어 명령어읽기 전용, 공유 가능
Data전역 변수, static 변수프로그램 시작 시 할당
Heap동적 할당 (malloc, new)런타임에 크기 변동, 위로 증가
Stack지역 변수, 함수 호출 정보함수 호출마다 push/pop, 아래로 증가

프로세스가 OS에서 받는 자원

┌─────── OS (운영체제) ───────┐
│                              │
│  프로세스 생성 요청 들어옴     │
│         │                    │
│         ▼                    │
│  ┌─ 할당하는 자원 ──────┐    │
│  │ ① 독립된 메모리 공간   │    │
│  │ ② CPU 시간 (스케줄링)  │    │
│  │ ③ PID (고유 식별자)    │    │
│  │ ④ 파일 디스크립터      │    │
│  │ ⑤ 네트워크 소켓       │    │
│  │ ⑥ 환경 변수           │    │
│  └──────────────────────┘    │
└──────────────────────────────┘

프로세스의 상태 (Process State)

        생성
         │
         ▼
┌──── New ─────┐
│ 프로세스 생성  │
└──────┬───────┘
       │ admit
       ▼
┌──── Ready ────┐ ◄──── 타이머 만료 (Preemption)
│ CPU 대기 중    │ ◄──── I/O 완료
└──────┬────────┘
       │ dispatch (CPU 할당)
       ▼
┌──── Running ──┐
│ CPU에서 실행 중 │
└──┬─────┬──────┘
   │     │
   │     │ I/O 요청, sleep 등
   │     ▼
   │  ┌──── Waiting (Blocked) ──┐
   │  │ I/O 완료를 기다리는 중    │
   │  └─────────────────────────┘
   │
   │ exit
   ▼
┌──── Terminated ──┐
│ 실행 완료, 자원 해제│
└──────────────────┘
상태설명
New프로세스 생성 중
Ready실행 준비 완료, CPU 할당 대기
RunningCPU를 점유하여 실행 중
WaitingI/O 등 외부 이벤트 대기 중
Terminated실행 완료, 자원 반납

PCB (Process Control Block)

OS가 각 프로세스를 관리하기 위해 유지하는 데이터 구조입니다.

┌──── PCB (프로세스 1234) ────┐
│ PID:           1234         │
│ 상태:          Running       │
│ PC(Program Counter): 0x04A2 │
│ 레지스터 값:    {eax, ebx...}│
│ 메모리 정보:    페이지 테이블  │
│ 열린 파일 목록: fd 0, 1, 2   │
│ CPU 사용 시간:  150ms        │
│ 우선순위:       5            │
└─────────────────────────────┘

Context Switch(문맥 교환) 시 현재 프로세스의 PCB를 저장하고, 다음 프로세스의 PCB를 복원합니다.

프로세스 간 독립성

각 프로세스는 독립된 메모리 공간을 가지므로 서로의 메모리에 직접 접근할 수 없습니다.

┌── 프로세스 A (PID: 1234) ──┐   ┌── 프로세스 B (PID: 5678) ──┐
│  가상 주소 공간              │   │  가상 주소 공간              │
│  ┌────────────────┐        │   │  ┌────────────────┐        │
│  │ Code │ Data    │        │   │  │ Code │ Data    │        │
│  │ Heap │ Stack   │        │   │  │ Heap │ Stack   │        │
│  └────────────────┘        │   │  └────────────────┘        │
│                             │   │                             │
│  A가 B의 메모리 접근 불가 X  │   │  B가 A의 메모리 접근 불가 X  │
└─────────────────────────────┘   └─────────────────────────────┘
                   │
            통신하려면 IPC 필요
IPC 방식설명
Pipe단방향 데이터 스트림
Shared Memory공유 메모리 영역 설정
Message Queue메시지 단위 송수신
Socket네트워크 기반 통신
Signal이벤트 알림 (SIGKILL 등)

프로세스 vs 스레드

항목프로세스스레드
메모리독립 공간같은 프로세스 내 공유
생성 비용큼 (메모리 복제)작음 (Stack만 별도)
통신IPC 필요 (느림)메모리 직접 공유 (빠름)
안정성하나 죽어도 다른 프로세스 무관하나 죽으면 전체 프로세스 영향
Context Switch비용 큼비용 작음
┌──── 프로세스 ─────────────────────────┐
│                                        │
│  Code │ Data │ Heap   ← 모든 스레드 공유│
│                                        │
│  ┌─ 스레드 A ─┐  ┌─ 스레드 B ─┐       │
│  │ Stack      │  │ Stack      │       │
│  │ PC         │  │ PC         │       │
│  └────────────┘  └────────────┘       │
└────────────────────────────────────────┘

실제 확인

# 현재 실행 중인 프로세스 확인
$ ps aux
PID   USER  COMMAND
1     root  /sbin/init
1234  user  java -jar app.jar
5678  user  /usr/bin/chrome
9012  user  python server.py

# 특정 프로세스의 스레드 확인
$ ps -T -p 1234
PID   SPID  COMMAND
1234  1234  java          ← main 스레드
1234  1235  java          ← GC 스레드
1234  1236  java          ← JIT 컴파일 스레드
1234  1237  java          ← worker 스레드

핵심 정리

프로세스는 실행 중인 프로그램의 인스턴스로, OS로부터 독립된 메모리 공간, CPU 시간, PID 등의 자원을 할당받습니다. 각 프로세스는 메모리가 격리되어 안정적이지만, 그만큼 생성 비용이 크고 통신에 IPC가 필요합니다. 이런 비용을 줄이기 위해 하나의 프로세스 안에서 여러 실행 흐름을 만드는 스레드 개념이 등장했습니다.

CSLOG에서 보기