프로세스 vs 쓰레드

기술노트

프로세스 vs 쓰레드

개요

프로세스(Process)와 쓰레드(Thread)는 운영체제에서 실행의 기본 단위를 나타내는 개념입니다. 두 개념은 컴퓨터 시스템의 자원 활용과 병렬 처리에 있어 핵심적인 역할을 하며, 프로그램 실행 방식과 성능에 중요한 영향을 미칩니다.

프로세스(Process)

정의

프로세스는 실행 중인 프로그램의 인스턴스로, 독립된 메모리 공간과 시스템 자원을 할당받아 실행되는 작업의 단위입니다.

특징

  • 독립적 메모리 공간: 각 프로세스는 독립된 메모리 영역(코드, 데이터, 스택, 힙)을 가짐
  • 자원 소유: 프로세스는 파일, I/O 장치 등 시스템 자원을 소유하고 관리
  • 보호 경계: 다른 프로세스의 메모리에 직접 접근 불가능
  • 무거운 컨텍스트 스위칭: 프로세스 간 전환 시 CPU 레지스터, 메모리 맵, 커널 자원 등 모두 저장/복원 필요
  • 통신 방법: IPC(Inter-Process Communication) 메커니즘을 통해 통신
    • 파이프(Pipe), 소켓(Socket), 공유 메모리(Shared Memory), 메시지 큐 등

프로세스의 상태

  • 생성(New): 프로세스가 생성되는 상태
  • 준비(Ready): CPU 할당을 기다리는 상태
  • 실행(Running): CPU를 할당받아 명령어를 실행 중인 상태
  • 대기(Blocked/Wait): I/O 완료 등 특정 이벤트 발생을 기다리는 상태
  • 종료(Terminated): 실행이 완료된 상태

프로세스 생성 방법

  • fork(): 부모 프로세스의 복사본으로 자식 프로세스 생성 (Unix/Linux)
  • exec(): 새로운 프로그램으로 프로세스 이미지 대체
  • CreateProcess(): Windows에서 새 프로세스 생성

쓰레드(Thread)

정의

쓰레드는 프로세스 내에서 실행되는 더 작은 실행 단위로, 프로세스의 자원을 공유하면서 독립적으로 실행됩니다.

특징

  • 자원 공유: 같은 프로세스 내 쓰레드들은 코드, 데이터 섹션, 열린 파일 등 자원 공유
  • 독립적 실행 경로: 각 쓰레드는 자체 프로그램 카운터, 스택, 레지스터 보유
  • 가벼운 컨텍스트 스위칭: 쓰레드 전환 시 프로세스 내 컨텍스트만 저장/복원
  • 직접 통신 가능: 같은 프로세스 내 쓰레드 간에는 공유 변수를 통한 직접 통신 가능
  • 동기화 필요: 공유 자원 접근 시 경쟁 조건(Race Condition) 방지를 위한 동기화 필요

쓰레드 유형

  • 사용자 수준 쓰레드(User-Level Thread):
    • 커널의 지원 없이 사용자 공간에서 관리
    • 커널이 인식하지 못함
    • 구현이 간단하지만 I/O 블로킹 시 전체 프로세스 블로킹
  • 커널 수준 쓰레드(Kernel-Level Thread):
    • 운영체제 커널에 의해 관리
    • 커널이 각 쓰레드를 인식하고 스케줄링
    • 하나의 쓰레드 블로킹 시에도 다른 쓰레드 실행 가능

쓰레드 생성 방법

  • pthread_create(): POSIX 쓰레드 라이브러리 (Unix/Linux)
  • CreateThread(): Windows API
  • Thread 클래스: Java, C# 등 고수준 언어에서 제공하는 쓰레드 객체

프로세스 vs 쓰레드 비교

프로세스와 쓰레드 비교
특성 프로세스 쓰레드
정의 독립적인 프로그램 실행 단위 프로세스 내의 작은 실행 단위
메모리 공간 각 프로세스마다 독립적 메모리 할당 프로세스의 메모리 공유 (스택은 별도)
통신 방식 IPC 메커니즘 필요 (소켓, 파이프 등) 공유 메모리를 통한 직접 통신
컨텍스트 스위칭 무거움 (전체 프로세스 상태 저장) 가벼움 (쓰레드 상태만 저장)
자원 소비 많은 자원 필요 적은 자원으로 생성 가능
안정성 한 프로세스 문제가 다른 프로세스에 영향 적음 한 쓰레드 문제가 전체 프로세스에 영향
생성 시간 상대적으로 오래 걸림 프로세스보다 빠름
적합한 환경 독립적 작업, 높은 안정성 요구 병렬 작업, 자원 공유 필요

멀티 프로세스 vs 멀티 쓰레드

멀티 프로세스

  • 장점
    • 하나의 프로세스가 죽어도 다른 프로세스에 영향 적음
    • 보안성과 안정성 높음
    • 각 프로세스마다 자원 보호
  • 단점
    • 프로세스 생성 및 컨텍스트 스위칭 오버헤드 큼
    • 프로세스 간 통신이 복잡하고 비용 높음
    • 자원 소모가 큼

멀티 쓰레드

  • 장점
    • 자원 공유로 메모리 사용량 감소
    • 컨텍스트 스위칭 오버헤드 적음
    • 통신 비용 낮음
    • 응답성 향상
  • 단점
    • 한 쓰레드 오류가 전체 프로세스에 영향
    • 동기화 이슈 (교착상태, 경쟁 조건)
    • 디버깅이 복잡함

문맥 교환(Context Switching)

정의

문맥 교환은 현재 실행 중인 프로세스나 쓰레드의 상태를 저장하고 다음 실행할 프로세스나 쓰레드의 상태를 복원하는 과정입니다.

프로세스 문맥 교환 단계

  1. 현재 프로세스의 상태 저장 (PCB - Process Control Block에 저장)
  2. 대기 큐에서 다음 프로세스 선택
  3. 새 프로세스의 상태 복원
  4. 새 프로세스로 CPU 제어권 이전

문맥 교환의 비용

  • 프로세스 간 문맥 교환: 메모리 맵, 커널 자원 등 모두 변경 필요
  • 쓰레드 간 문맥 교환: 동일 프로세스 내에서는 메모리 맵 변경 불필요
  • 캐시 미스: 프로세스 변경 시 캐시 내용이 무효화되어 성능 저하

쓰레드의 필요성 및 활용 사례

필요성

  • 반응성 향상: UI 쓰레드와 작업 쓰레드 분리로 응답성 개선
  • 자원 활용 최적화: 유휴 CPU 코어 활용
  • 비용 효율성: 프로세스보다 적은 자원으로 병렬 작업 수행
  • 데이터 공유 효율화: 동일 주소 공간 내 데이터 접근

활용 사례

  • 웹 서버: 각 요청을 별도 쓰레드로 처리
  • 게임 엔진: 렌더링, 물리 계산, AI 등을 별도 쓰레드로 처리
  • 멀티미디어 애플리케이션: 인코딩/디코딩, UI 처리 분리
  • 병렬 계산: 대용량 데이터 처리, 과학 계산
  • 백그라운드 작업: 주 작업과 별개로 진행되는 작업

쓰레드 프로그래밍 모델

기본 모델

  • 1:1 모델: 각 사용자 쓰레드가 하나의 커널 쓰레드에 매핑
  • N:1 모델: 여러 사용자 쓰레드가 하나의 커널 쓰레드에 매핑
  • N:M 모델: N개의 사용자 쓰레드가 M개의 커널 쓰레드에 매핑

쓰레드 풀

  • 미리 생성된 쓰레드를 재사용하여 쓰레드 생성/소멸 비용 절감
  • 동시 실행 쓰레드 수 제한으로 시스템 안정성 향상
  • Java의 ExecutorService, C#의 ThreadPool 등

쓰레드 동기화 기법

경쟁 조건(Race Condition)

여러 쓰레드가 공유 자원에 동시 접근할 때 결과가 실행 순서에 의존하는 상황

동기화 메커니즘

  • 뮤텍스(Mutex): 한 번에 하나의 쓰레드만 자원 접근 허용
  • 세마포어(Semaphore): 지정된 수의 쓰레드만 자원 접근 허용
  • 모니터(Monitor): 객체에 대한 접근을 동기화 (Java의 synchronized)
  • 원자적 연산(Atomic Operations): 중단 없이 완료되는 연산
  • 스핀락(Spinlock): 자원이 해제될 때까지 루프를 돌며 대기

관련 주제

  • 운영체제
  • 병렬 프로그래밍
  • 동시성 프로그래밍
  • 교착상태(Deadlock)
  • 스케줄링 알고리즘
  • 쓰레드 안전성(Thread Safety)