프로세스와 스레드

프로세스와 스레드의 기본 개념

프로세스와 스레드를 한마디로 정의하면 다음과 같습니다:

프로세스 (Process)스레드 (Thread)
운영체제로부터 자원을 할당받은 작업의 단위프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위

프로그램과 프로세스

프로그램 (Program)

프로그램은 윈도우의 *.exe 파일이나 Mac의 *.dmg 파일과 같은 컴퓨터에서 실행할 수 있는 파일을 의미합니다. 단, 아직 파일을 실행하지 않은 상태이기 때문에 정적 프로그램(Static Program)이라고 부릅니다.

  • 파일이 저장 장치에 있지만 메모리에는 올라가 있지 않은 정적인 상태
  • 쉽게 말해 그냥 코드 덩어리

프로세스 (Process)

프로세스는 프로그램을 실행시켜 정적인 프로그램이 동적으로 변하여 프로그램이 돌아가고 있는 상태를 말합니다. 즉, 컴퓨터에서 작업 중인 프로그램을 의미합니다.

  • 메모리에 적재되고 CPU 자원을 할당받아 프로그램이 실행되고 있는 상태
  • 그 코드 덩어리를 실행한 것

모든 프로그램은 운영체제가 실행되기 위한 메모리 공간을 할당해 줘야 실행될 수 있습니다. 프로그램을 실행하는 순간 파일은 컴퓨터 메모리에 올라가게 되고, 운영체제로부터 시스템 자원(CPU)을 할당받아 프로그램 코드를 실행시켜 우리가 서비스를 이용할 수 있게 됩니다.

프로세스의 자원 구조

프로그램이 실행되어 프로세스가 만들어지면 운영체제로부터 메모리 공간을 할당받게 됩니다. 이 메모리 공간은 다음과 같은 4가지 영역으로 구성됩니다:

메모리 영역 구성

높은 주소
┌─────────────────┐
│     Stack       │ ← 동적 영역 (함수 호출 시 증가/감소)
│        ↓        │
│                 │
│        ↑        │
│      Heap       │ ← 동적 영역 (동적 할당 시 증가/감소)
│                 │
├─────────────────┤
│     Data        │ ← 정적 영역 (프로그램 시작 시 크기 결정)
│   (.data,       │
│   .rodata,      │
│   .bss)         │
├─────────────────┤
│     Code        │ ← 정적 영역 (프로그램 시작 시 크기 결정)
│    (Text)       │
└─────────────────┘
낮은 주소

1. 코드 영역 (Code / Text)

  • 역할: 프로그래머가 작성한 프로그램 함수들의 코드가 CPU가 해석 가능한 기계어 형태로 저장되어 있는 영역
  • 특징:
    • 읽기 전용(Read-Only) 영역
    • 프로그램 시작 시 크기가 결정되는 정적 영역
    • 여러 프로세스가 같은 프로그램을 실행하면 코드 영역은 공유될 수 있음

2. 데이터 영역 (Data)

  • 역할: 코드가 실행되면서 사용하는 전역 변수나 각종 데이터들이 모여있는 영역
  • 특징: 프로그램 시작 시 크기가 결정되는 정적 영역
  • 세부 영역:
영역설명예시
.data전역 변수 또는 static 변수 등 프로그램이 사용하는 데이터int global_var = 10;
.bss초기값 없는 전역 변수, static 변수가 저장int uninitialized_var;
.rodataconst 같은 상수 키워드 선언된 변수나 문자열 상수가 저장const int MAX_SIZE = 100;

3. 스택 영역 (Stack)

  • 역할: 지역 변수와 같은 호출한 함수가 종료되면 되돌아올 임시적인 자료를 저장하는 독립적인 공간
  • 특징:
    • 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸
    • LIFO (Last In First Out) 구조
    • 스택 포인터가 높은 주소에서 낮은 주소 방향으로 증가
    • 스택 영역을 초과하면 Stack Overflow 에러 발생
    • 프로세스가 실행되는 동안 크기가 늘어났다 줄어들기도 하는 동적 영역

스택에 저장되는 것들:

  • 지역 변수
  • 함수 매개변수
  • 함수의 반환 주소
  • 함수 호출 정보

4. 힙 영역 (Heap)

  • 역할: 생성자, 인스턴스와 같은 동적으로 할당되는 데이터들을 위해 존재하는 공간
  • 특징:
    • 사용자에 의해 메모리 공간이 동적으로 할당되고 해제됨
    • 프로세스가 실행되는 동안 크기가 늘어났다 줄어들기도 하는 동적 영역
    • 스택과 반대로 낮은 주소에서 높은 주소 방향으로 증가
    • 프로그래머가 직접 관리해야 함 (메모리 누수 주의)

힙에 저장되는 것들:

  • malloc(), new 등으로 동적 할당된 메모리
  • 객체 인스턴스
  • 동적 배열

정적 영역 vs 동적 영역

위의 그림에서 Stack과 Heap 영역이 위아래로 화살표가 표시된 것을 볼 수 있는데, 이는 다음과 같은 의미입니다:

  • 정적 영역 (Code, Data):

    • 프로그램이 시작될 때 크기가 결정됨
    • 프로그램 실행 중 크기 변경 불가
    • 컴파일 타임에 메모리 크기 결정
  • 동적 영역 (Stack, Heap):

    • 프로세스가 실행되는 동안 크기가 늘어났다 줄어들기도 함
    • 런타임에 메모리 크기 결정
    • Stack은 함수 호출에 따라, Heap은 동적 할당에 따라 크기 변경

여러 프로세스의 메모리 구조

프로그램이 여러 개 실행된다면 메모리에 프로세스들이 담길 주소 공간이 생성되게 되고, 각 프로세스마다 독립적인 Code, Data, Stack, Heap 공간이 만들어지게 됩니다.

메모리
┌─────────────────────────┐
│   프로세스 A              │
│   ┌─────────────────┐   │
│   │     Stack       │   │
│   │      Heap       │   │
│   │     Data        │   │
│   │     Code        │   │
│   └─────────────────┘   │
├─────────────────────────┤
│   프로세스 B              │
│   ┌─────────────────┐   │
│   │     Stack       │   │
│   │      Heap       │   │
│   │     Data        │   │
│   │     Code        │   │
│   └─────────────────┘   │
└─────────────────────────┘

각 프로세스는 독립적인 메모리 공간을 가지므로, 한 프로세스의 메모리에 다른 프로세스가 직접 접근할 수 없습니다. 이는 프로세스 간 안정성과 보안을 보장합니다.

스레드 (Thread)

프로세스의 한계

과거에는 프로그램을 실행할 때 프로세스 하나만을 사용했습니다. 하지만 기술이 발전됨에 따라 프로그램이 복잡해지고 다채로워짐으로써 프로세스 작업 하나만을 사용해서 프로그램을 실행하기에는 한계가 있었습니다.

동일한 프로그램을 여러 개의 프로세스로 만들게 되면, 그만큼 메모리를 차지하고 CPU에서 할당받는 자원이 중복되게 됩니다. 스레드(Thread)는 이러한 프로세스 특성의 한계를 해결하기 위해 탄생했습니다.

스레드의 개념

스레드란, 하나의 프로세스 내에서 동시에 진행되는 작업 갈래, 흐름의 단위를 말합니다.

예를 들어, 웹 브라우저에서 파일을 다운로드하면서 동시에 다른 웹페이지를 탐색할 수 있는 것은 하나의 프로세스 내에서 여러 스레드가 동시에 작업을 수행하기 때문입니다.

프로세스 vs 스레드 비교

자원 공유

구분프로세스스레드
메모리 공간독립적인 메모리 공간 (별도의 주소 공간)프로세스의 메모리 공간 공유
코드/데이터/힙각자 독립적으로 보유프로세스 내에서 공유
스택각자 독립적인 스택각 스레드마다 독립적인 스택
레지스터각자 독립적인 레지스터각 스레드마다 독립적인 레지스터
파일 디스크립터각자 독립적으로 보유프로세스 내에서 공유
전역 변수공유 불가공유 가능

통신 방식

구분프로세스스레드
통신 방법IPC (Inter-Process Communication)<br>- 파이프, 소켓, 공유 메모리 등공유 메모리 공간을 통한 직접 접근
통신 비용높음 (컨텍스트 스위칭 비용)낮음 (같은 주소 공간 사용)
동기화필요 없음 (독립적)필요함 (공유 자원 접근 시)

생성 및 관리

구분프로세스스레드
생성 비용높음 (메모리 복사 필요)낮음 (기존 프로세스 자원 공유)
컨텍스트 스위칭느림 (메모리 공간 전환)빠름 (레지스터만 전환)
독립성높음 (하나가 죽어도 다른 프로세스에 영향 없음)낮음 (하나가 죽으면 전체 프로세스 종료 가능)

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

멀티프로세스 (Multi-Process)

  • 여러 개의 프로세스를 동시에 실행
  • 각 프로세스는 독립적인 메모리 공간을 가짐
  • 프로세스 간 통신이 어렵고 비용이 높음
  • 하나의 프로세스가 죽어도 다른 프로세스에 영향 없음

장점:

  • 프로세스 간 독립성으로 안정성 높음
  • 하나의 프로세스 오류가 다른 프로세스에 영향 없음

단점:

  • 메모리 사용량이 많음
  • 컨텍스트 스위칭 비용이 높음
  • 프로세스 간 통신이 복잡함

멀티스레드 (Multi-Thread)

  • 하나의 프로세스 내에서 여러 스레드를 동시에 실행
  • 스레드 간 메모리 공간을 공유
  • 스레드 간 통신이 쉽고 비용이 낮음
  • 하나의 스레드 오류가 전체 프로세스에 영향 줄 수 있음

장점:

  • 메모리 사용량이 적음
  • 컨텍스트 스위칭이 빠름
  • 스레드 간 통신이 쉬움
  • 자원 공유가 효율적

단점:

  • 동기화 문제 발생 가능 (Race Condition, Deadlock)
  • 하나의 스레드 오류가 전체 프로세스에 영향
  • 디버깅이 어려움

실제 사용 예시

멀티프로세스 사용 사례

  • 웹 브라우저의 탭 (각 탭이 독립적인 프로세스)
  • 운영체제의 여러 프로그램 동시 실행
  • 서버의 여러 워커 프로세스

멀티스레드 사용 사례

  • 웹 브라우저 내에서 파일 다운로드와 웹페이지 탐색 동시 수행
  • 워드 프로세서에서 타이핑과 자동 저장 동시 수행
  • 게임에서 렌더링과 물리 엔진 동시 처리
  • 웹 서버의 요청 처리 (각 요청을 스레드로 처리)

정리

  1. 프로세스: 운영체제로부터 자원을 할당받은 작업의 단위로, 독립적인 메모리 공간을 가짐
  2. 스레드: 프로세스 내에서 실행되는 흐름의 단위로, 프로세스의 메모리 공간을 공유
  3. 자원 공유: 프로세스는 독립적, 스레드는 공유 메모리 공간 사용
  4. 통신: 프로세스는 IPC 필요, 스레드는 공유 메모리로 직접 접근
  5. 선택 기준: 안정성이 중요하면 멀티프로세스, 성능과 효율성이 중요하면 멀티스레드