본문 바로가기

프로세스와 스레드 Process and Thread

@iamrain2025. 11. 19. 10:25

1. 프로세스 (Process)

1.1. 정의

프로세스란 간단히 말해 '실행 중인 프로그램'이다. 디스크에 저장된 정적인 프로그램(코드 덩어리)이 메모리에 적재되어, 운영체제로부터 CPU 시간, 메모리 등의 자원을 할당받아 생명을 얻은 동적인 개체를 의미한다.

1.2. 메모리 구조

프로세스는 운영체제로부터 독립된 자신만의 메모리 공간을 할당받는다. 이 주소 공간은 크게 네 가지 영역으로 구성된다.

  • 코드 영역 (Code or Text Section): 실행할 프로그램의 코드가 기계어 형태로 저장되는 공간. 읽기 전용(Read-only)이다.
  • 데이터 영역 (Data Section): 프로그램의 전역 변수(Global variables)와 정적 변수(Static variables)가 저장되는 공간. 프로그램 시작 시 할당되어 종료 시 소멸된다.
  • 힙 영역 (Heap Section): 프로그래머가 동적으로 할당하고 해제하는 메모리 공간. malloc(), new 연산으로 할당되며, 런타임(Runtime) 시에 크기가 결정된다.
  • 스택 영역 (Stack Section): 함수 호출 시 생성되는 지역 변수, 매개변수, 반환 주소 등이 저장되는 공간. 함수 호출이 완료되면 사라진다. 컴파일 타임에 크기가 결정된다.

1.3. 특징

  • 자원의 독립성: 각 프로세스는 독립된 메모리 주소 공간을 가지므로, 다른 프로세스의 자원에 직접 접근할 수 없다. 이는 안정성을 보장하지만, 데이터를 공유하기 어렵게 만든다.
  • 프로세스 간 통신 (IPC, Inter-Process Communication): 독립성 때문에, 프로세스 간에 데이터를 주고받으려면 운영체제가 제공하는 IPC 메커니즘(e.g., 파이프, 소켓, 공유 메모리, 메시지 큐)을 이용해야 한다.

2. 스레드 (Thread)

2.1. 정의

스레드'프로세스 내에서 실행되는 흐름의 단위'이다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있으며, 이를 멀티스레딩(Multi-threading)이라고 한다. 스레드는 '경량 프로세스(Lightweight Process)'라고도 불린다.

2.2. 메모리 구조

스레드는 프로세스의 자원을 공유하면서, 동시에 자신만의 독립적인 실행 상태를 가진다.

  • 공유하는 자원: 프로세스의 코드, 데이터, 힙 영역을 다른 스레드들과 공유한다.
  • 독립적인 자원: 각 스레드는 자신만의 스택(Stack), 프로그램 카운터(PC), 그리고 레지스터 집합을 가진다. 이를 통해 독립적인 함수 호출과 실행 흐름을 유지할 수 있다.

3. 구조적 차이 및 문맥 교환 (Context Switching)

3.1. 구조적 차이 요약

구분 프로세스 (Process) 스레드 (Thread)
정의 실행 중인 프로그램 프로세스 내의 실행 흐름 단위
메모리 독립적인 주소 공간 할당 Code, Data, Heap 공유 / Stack, PC, Register 독립
생성 비용 비쌈 (자원 할당, PCB 생성 등) 저렴 (공유 자원 활용)
통신 IPC 필요 (복잡, 느림) 공유 메모리 통해 가능 (간단, 빠름)
안정성 높음 (한 프로세스 오류가 다른 프로세스에 영향 X) 낮음 (한 스레드 오류가 전체 프로세스에 영향 O)

3.2. 문맥 교환 (Context Switching)

문맥 교환이란 CPU가 현재 실행 중인 작업(Context)을 중단하고, 다른 작업으로 전환하면서 이전 작업의 상태를 저장(Save)하고 새로운 작업의 상태를 복원(Restore)하는 과정이다.

  • 프로세스 문맥 교환:
    1. 현재 실행 중인 프로세스의 정보(PCB, Process Control Block)를 저장한다.
    2. 다음으로 실행할 프로세스의 PCB를 불러온다.
    3. 이 과정에서 메모리 주소 공간 전체가 교체되므로, CPU 캐시 메모리에 있던 데이터가 무효화되고 TLB(Translation Lookaside Buffer)가 초기화(flush)된다.
    4. 이 캐시 및 TLB 초기화로 인한 성능 저하가 크기 때문에, 프로세스 문맥 교환은 매우 비싼(expensive) 작업이다.
  • 스레드 문맥 교환:
    1. 현재 실행 중인 스레드의 정보(TCB, Thread Control Block: PC, 레지스터, 스택 포인터 등)를 저장한다.
    2. 같은 프로세스 내의 다른 스레드의 TCB를 불러온다.
    3. 메모리 주소 공간을 공유하므로, 캐시나 TLB를 초기화할 필요가 없다.
    4. 따라서 스레드 문맥 교환은 프로세스 문맥 교환에 비해 훨씬 빠르고 오버헤드가 적다.

4. 동시성 이슈와 동기화 (Concurrency & Synchronization)

멀티스레딩 환경에서는 여러 스레드가 코드, 데이터, 힙 영역을 공유하기 때문에 동시성 이슈가 발생할 수 있다.

4.1. 경쟁 상태 (Race Condition)

둘 이상의 스레드가 공유 데이터에 동시에 접근하여 조작하고, 그 실행 결과가 스레드의 접근 순서에 따라 달라지는 예측 불가능한 상황을 말한다.

4.2. 임계 구역 (Critical Section)

공유 자원에 접근하는 코드 영역을 의미한다. 동시성 문제를 해결하려면, 한 번에 하나의 스레드만이 이 구역을 실행하도록 보장해야 한다. 이를 상호 배제(Mutual Exclusion)라고 한다.

4.3. 동기화 (Synchronization) 기법

임계 구역 문제를 해결하고 실행 순서를 제어하여 데이터의 일관성을 유지하는 기법들이다.

  • 뮤텍스 (Mutex, MUTual EXclusion)
    • 임계 구역에 오직 하나의 스레드만 들어갈 수 있도록 하는 잠금(lock) 메커니즘이다.
    • 스레드는 임계 구역에 들어가기 전 lock()을 획득해야 하며, 나올 때 반드시 unlock()을 통해 잠금을 해제해야 한다.
    • 소유권 개념이 있어, lock()을 건 스레드만이 unlock()할 수 있다.
  • 세마포어 (Semaphore)
    • 지정된 개수(N)의 스레드만이 공유 자원에 동시에 접근할 수 있도록 허용하는 계수기(counter) 기반의 기법이다.
    • wait()(또는 P) 연산으로 카운트를 감소시키며 자원을 획득하고, signal()(또는 V) 연산으로 카운트를 증가시키며 자원을 반납한다.
    • 카운트가 1인 바이너리 세마포어는 뮤텍스와 유사하게 동작할 수 있지만, 뮤텍스와 달리 소유권 개념이 없다. (자원을 획득한 스레드가 아니더라도 다른 스레드가 자원을 반납할 수 있음)
  • 모니터 (Monitor)
    • 뮤텍스와 조건 변수(Condition Variables)를 결합하여, 프로그래머가 더 쉽고 안전하게 동기화를 구현할 수 있도록 돕는 고급 동기화 구조다.
    • Java의 synchronized 키워드, C#의 lock 문 등이 모니터를 언어 차원에서 구현한 예다. 프로그래머의 lock/unlock 실수를 방지해준다.

5. 멀티 프로세스 vs. 멀티 스레드: 언제 무엇을 쓸까?

  멀티 프로세스 (Multi-process) 멀티 스레드 (Multi-thread)
장점 안정성: 하나의 프로세스가 비정상 종료되어도 다른 프로세스에 영향을 주지 않는다. 효율성: 자원 공유로 생성 및 문맥 교환이 빠르고, 통신 비용이 적다.
단점 비효율성: 생성 및 문맥 교환 오버헤드가 크고, IPC 구현이 복잡하다. 안정성: 하나의 스레드가 비정상 종료되면 전체 프로세스가 종료될 수 있다. 동기화 문제로 설계가 복잡하다.
사용처 - 안정성이 최우선인 경우
- 각기 다른 역할을 하는 독립적인 프로그램을 동시에 실행할 때 (e.g., 웹 브라우저의 각 탭)
- 하나의 작업을 여러 단위로 나누어 동시에 처리하여 성능을 높이고자 할 때
- 빠른 응답성이 중요한 GUI 애플리케이션, 웹 서버 등

6. 요약

 프로세스는 '실행 중인 프로그램'으로, 운영체제로부터 자신만의 독립된 메모리 공간을 할당받습니다. 반면 스레드는 '프로세스 내에서 실행되는 흐름의 단위'로, 자신이 속한 프로세스의 메모리(코드, 데이터, 힙)를 다른 스레드들과 공유합니다.

 가장 큰 차이는 자원의 독립성입니다. 프로세스는 각자 독립적인 자원을 가지므로 안정성이 높지만, 생성과 문맥 교환 시 오버헤드가 크고 프로세스 간 통신이 복잡합니다. 반면 스레드는 자원을 공유하므로 생성과 문맥 교환이 매우 빠르고 통신이 간단하지만, 하나의 스레드에 문제가 생기면 전체 프로세스가 영향을 받을 수 있고, 공유 자원 접근 시 '동기화' 문제를 신경 써야 하는 단점이 있습니다.

 따라서 멀티 프로세스는 안정성이 중요한 웹 브라우저의 각 탭처럼, 서로 영향을 주지 않아야 하는 독립적인 작업들에 주로 사용됩니다. 멀티 스레드는 하나의 작업을 동시에 처리하여 성능을 극대화해야 하는 웹 서버나, 빠른 응답성이 중요한 GUI 애플리케이션 등에서 주로 사용됩니다.

'Computer Science' 카테고리의 다른 글

TCP와 UDP  (0) 2025.11.24
IPC (Inter-Process Communication) 메커니즘  (0) 2025.11.21
CPU 스케줄링 CPU Scheduling  (0) 2025.11.19
캐시 메모리 Cache Memory  (0) 2025.11.19
CPU  (0) 2025.11.19
iamrain
@iamrain :: Annals of Unreal

iamrain 님의 블로그 입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차