[OS] 프로세스 & 스레드

do_it·2025년 9월 30일

os

목록 보기
1/13

0. 프로세스

운영체제는 프로세스를 생성·관리·제어함으로써 시스템 자원을 효율적이고 안전하게 사용할 수 있도록 하는 관리자

  • 프로그램이 실행되면 운영체제가 이를 프로세스로 생성
  • 프로세스마다 고유한 자원을 할당하고 관리 / 제어
  • 동시에 여러 프로세스를 실행하는 멀티태스킹 환경 제공

프로세스란?

디스크에 저장된 정적인 프로그램 코드가 메모리에 올라와서 CPU에서 실행될 때의 활동 단위

  • 운영 체제 관점: 프로세스 = 실행 단위
    OS는 프로그램이 실행되면 이를 프로세스로 바꾸어 관리함
    프로세스는 OS가 자원(CPU, 메모리 등)을 할당하는 기본 단위
  • CPU 관점: 프로세스 = 스케줄링 단위
    CPU는 한 번에 하나의 실행 흐름만 처리할 수 있으므로
    OS는 어떤 프로세스 / 스레드에게 CPU를 줄지 결정함

프로그램 & 프로세스

프로그램 (Program)프로세스 (Process)
개념디스크에 저장된 수동적(Passive)인 명령어와 데이터의 집합메모리에 적재되어 실행되는 능동적(Active)인 개체
존재파일 형태로 저장장치(하드디스크)에 존재메모리(RAM)에 존재하며 CPU 자원을 할당받음
상태실행 상태가 없고 정적임생성, 준비, 실행, 대기, 종료 등 동적인 상태를 가짐

프로그램: 코드 그 자체 (파일, 정적)

프로세스: 실행 중인 프로그램 (동적)


[프로그램 → 프로세스 전환과정]

[실행파일] → [로더가 분석] → [RAM에 적재] → [PCB 생성] → [프로세스 스케줄러에 등록] → [실행]
  1. 프로그램 실행 요청
  2. OS가 해당 프로그램의 실행 파일을 디스크에서 읽음 (로딩)
    • OS의 로더가 실행 파일을 분석함
    • 실행 파일을 파싱하여 코드 영역, 데이터 영역, 라이브러리 정보 등을 확인
  3. 실행에 필요한 데이터, 코드 등을 RAM(주기억 장치)에 적재 & 프로세스 생성
    • OS는 메모리 관리 시스템을 통해 해당 정보를 RAM에 로드함
    • 프로그램의 코드, 전역 변수, 초기데이터를 RAM에 올림
    • 힙, 스택 메모리 공간 메모리 공간, 레지스터, 스택, 힙 등을 각각 할당
  4. OS가 프로세스 제어 블록 (PCB) 생성
    • 고유한 PID (Process ID)를 부여
    • 프로그램 카운터, 레지스터 상태, 메모리 정보, 파일 디스크립터 등을 저장
  5. CPU 스케줄러에 등록
    • 이 프로세스는 Ready 상태가 되어 CPU 스케줄러에 등록됨
    • OS가 CPU를 할당하면, 프로세스가 실행 시작됨
  • [e.g.]
    워드 프로세서는 프로그램이고,
    워드 아이콘을 클릭하여 문서를 편집하는 순간 메모리에 올라와 실행되는 그 워드 세션 하나가 프로세스가 됨
    같은 워드 프로그램이라도 여러 개의 문서를 열면 여러 개의 독립된 프로세스가 실행될 수 있음

  • [e.g.]
    워드 프로세서는 프로그램이고,
    워드 아이콘을 클릭하여 문서를 편집하는 순간 메모리에 올라와 실행되는 그 워드 세션 하나가 프로세스가 됨
    같은 워드 프로그램이라도 여러 개의 문서를 열면 여러 개의 독립된 프로세스가 실행될 수 있음


1. 프로세스의 주소공간

운영체제가 해당 프로세스에 할당하는 가상의 메모리 영역

이 공간은 프로세스가 실행되는 데 필요한 모든 명령어와 데이터를 담고 있으며

크게 4가지 주요 영역으로 나뉨

    낮은 주소
  ┌────────────┐
  │   Code     │ ← 실행 코드 (.text)
  ├────────────┤
  │ Initialized Data (.data) │ ← 초기화된 전역/정적 변수
  ├────────────┤
  │ Uninitialized Data (.bss)│ ← 초기화되지 않은 전역/정적 변수
  ├────────────┤
  │   Heap     │ ← 동적 할당 (malloc, new 등)
  │ (위로 증가 ↑) │
  ├────────────┤
  │   ...       │ ← 빈 공간 (heap과 stack 사이)
  ├────────────┤
  │   Stack    │ ← 함수 호출, 지역 변수 등
  │ (아래로 감소 ↓) │
  └────────────┘
    높은 주소
  • Code, Data (.data/.bss): 고정 영역 (프로그램 시작 시 함께 로드)
  • Heap: 동적으로 늘어남 (위로)
  • Stack: 함수 호출 시 사용, 위에서 아래로 자람
  • Heap과 Stack은 서로 반대 방향으로 커지며, 충돌 위험 있음

1. 코드 영역 (Code Segment)

프로세스가 실행할 명렁어 코드가 저장되는 공간

  • 코드 영역의 내용은 실행 도중에 바뀌면 안 되므로, 보통 읽기 전용으로 설정됨
  • 개발자가 작성한 소스 코드가 컴파일된 기계어 명령어가 여기에 위치함
  • 여러 프로세스가 동일한 프로그램을 실행하는 경우, 메모리 절약을 위해 코드 영역을 공유할 수 있음

2. 데이터 영역 (Data Segment)

프로그램이 사용하는 전역 변수와 정적 변수가 저장되는 공간

  • 프로그램이 시작될 때 할당되고, 종료될 때 해제됨
  • 변수에 저장된 값은 실행 중에 변경될 수 있으므로 읽기 /쓰기가 가능
  • 초기화된 데이터: 코드가 시작될 때 지정된 전역 및 정적 변수
  • 초기화되지 않은 데이터(BSS): 값이 0이나 NULL 등으로 초기화되는 전역 및 정적 변수

3. 힙 영역 (Heap Segment)

프로세스가 실행되는 도중에 동적으로 메모리를 할당받을 때 사용하는 공간

  • 프로그램 실행 중 필요할 때마다 크기를 늘리거나(할당) 줄일 수 있음(해제)
  • 자바에서 new 키워드를 사용하여 생성되는 모든 객체나 배열이 이 힙 영역에 저장됨

4. 스택 영역 (Stack Segment)

함수의 호출과 관련된 임시적인 데이터가 저장되는 곳

  • 데이터가 후입선출(LIFO) 방식으로 관리됨
  • 함수가 호출될 때마다 프레임이 추가되고, 함수가 반환될 때마다 프레임이 제거됨
  • 힙 영역과 달리 스택 영역은 각 스레드마다 독립적으로 존재하며, 운영체제나 컴파일러에 의해 자동으로 할당 및 해제됨
  • 지역변수, 매개변수, 복귀주소

프로세스 상태 (Process State)

운영체제는 여러 프로세스를 동시에 다루기 위해 각 프로세스의 상태를 관리함

운영체제가 각 상태 간 전환을 스케줄링, 인터럽트, 시스템 콜 등을 통해 조정함

  • New(생성) : 프로세스가 막 생성되어 PCB를 할당받는 등 초기화 작업이 진행 중인 상태
  • Ready(준비): 프로세스가 메모리에 적재되었고, CPU를 할당받기를 기다리는 상태
  • Running(실행):프로세스가 CPU를 할당받아 실제로 명령어를 실행하고 있는 상태
  • Waiting (Blocked, 대기): 프로세스가 입출력(I/O) 작업 완료나 다른 이벤트가 발생하기를 기다리는 상태
  • Terminated (종료): 프로세스의 실행이 완료되고 시스템 자원(메모리 등)이 회수되는 최종 상태


2. 프로세스 제어블록 (PCB, Process Control Block)

운영체제가 프로세스를 추적, 관리하기 위해 유지하는 핵심 자료 구조

⇒ 프로세스의 모든 중요 정보를 담고 있는 스냅샷의 역할

운영체제는 이 PCB를 통해 프로세스의 상태를 파악하고, CPU 자원을 할당

  • 어디에 존재하는가?
    PCB는 프로세스의 가장 중요한 정보를 담고 있으므로, 일반 사용자 프로그램이 임의로 접근하거나 수정하지 못하도록 운영체제의 커널 영역 내부에 생성되고 관리됨
  • 생성과 소멸
    프로세스가 생성될 때 PCB가 만들어지고, 프로세스가 종료될 때 PCB도 폐기됨

[주요 역할]

  1. 프로세스 상태 관리
    프로세스의 현재 상태(준비, 실행, 대기 등)를 기록하여 스케줄러가 다음 실행할 프로세스를 결정하는 데 사용 → 문맥 교환에 핵심 도구
  2. 자원 관리
    프로세스에게 할당된 메모리, 파일, 입출력 장치 등의 자원 정보를 기록하여
    자원을 효율적으로 관리하고 회수

PCB가 포함하는 주요 정보

운영체제마다 포함되는 세부 정보는 다를 수 있지만, 일반적으로 다음 정보들을 포함함

구분정보 항목설명
식별 정보프로세스 ID (PID)운영체제가 각 프로세스를 구별하기 위해 부여하는 고유 번호
사용자/그룹 ID프로세스를 생성한 사용자의 정보
상태 정보프로세스 상태 (Process State)현재 프로세스가 Ready, Running, Waiting 등 어떤 상태에 있는지 기록
CPU 상태프로그램 카운터 (Program Counter, PC)프로세스가 다음에 실행해야 할 명령어의 주소를 가리킵니다
CPU 레지스터 값실행 중이던 시점의 누산기, 인덱스 레지스터 등 CPU 레지스터의 모든 값을 저장 (문맥 교환 시 가장 중요)
메모리 정보메모리 관리 정보프로세스에 할당된 메모리 영역(코드, 데이터, 힙, 스택)의 주소와 크기, 페이지 테이블 정보 등
스케줄링 정보우선순위CPU 스케줄러가 프로세스 선택에 참고하는 우선순위 값
스케줄링 파라미터CPU 사용 시간, 대기 시간 등 스케줄링에 필요한 추가 정보
I/O 및 파일 정보I/O 상태 정보프로세스에 할당된 입출력 장치 목록
열린 파일 목록프로세스가 현재 사용 중인 파일에 대한 정보(파일 디스크립터)


3. 문맥 교환 (Context Switching)

문맥 교환?

⇒ CPU의 제어권을 현재 실행 중인 프로세스(A)에서 다른 프로세스(B)로 넘기는 과정

하나의 프로세스 실행을 멈추고 다른 프로세스로 CPU 제어권을 넘겨줄 때,
중단된 프로세스의 현재 상태(CPU 레지스터 값, 프로그램 카운터 등의 Context)를 PCB에 저장
이후 해당 프로세스가 다시 CPU를 할당받을 때, PCB에 저장된 정보를 복원하여
중단했던 지점부터 상태를 PCB로부터 불러와 CPU 레지스터에 로드하는 일련의 작업

[목적] 시분할 시스템

단일 코어 CPU 환경에서 여러 프로세스가 짧은 시간 간격으로 CPU를 번갈아 사용하게 하여,
사용자에게 모든 프로그램이 동시에 실행되는 것처럼 느끼게 하기 위함


문맥 교환 과정

  1. 현재 Context 저장 (Context Save)
    1- 인터럽트 / 시스템 호출 발생으로 현재 실행중인 프로세스가 중단됨
    2- 상태 기록: 현재 시점의 CPU 레지스터 값, 프로그램 카운터, 스택 포인터 등 모든 실행 문멕을 PCB에 저장
  2. 다음 프로세스 선택 및 교체
    1 - 스케줄링:
    OS의 스케줄러가 준비 상태에 있는 프로세스들 중에서 다음 실행할 프로세스를 선택
    2- PCB 포인터 변경: CPU가 바라보는 PCB의 포인터를 다음 프로세스로 변경
  3. Context 복원 (Context Restore)
    1 - 상태 로드:
    OS는 선택된 프로세스의 PCB에 저장되어 있던 문맥 정보를 CPU 레지스터로 로드하여 복원
    2- 실행 재개: 복원된 PC가 가리키는 주소부터 실행을 재개

문맥 교환 발생 시점

자발적 / 비자발적

  • 시분할 (Time Sharing) / 타이머 인터럽트: 비자발적 특정 프로세스에 할당된 CPU 사용 시간(Time Slice)이 만료되었을 때,
    다른 프로세스에게 CPU를 넘겨주기 위해 발생
  • 시스템 호출 (System Call) / I/O 대기: 자발적 프로세스가 파일 입출력(I/O)과 같은 느린 작업이 필요하여 운영체제에 요청(시스템 호출)하고, 그 결과가 나올 때까지 대기 상태(Waiting)로 전환될 때 발생
  • 우선순위가 높은 프로세스 등장: 비자발적 현재 실행 중인 프로세스보다 우선순위가 훨씬 높은 새로운 프로세스가 준비 상태로 들어왔을 때, 기존 프로세스를 중단시키고 제어권 넘김

문맥 교환의 오버헤드

  • 시간 비용 (Latency)
    문맥 교환이 일어나는 동안 CPU는 사용자 프로세스의 명령어를 실행하지 않고 PCB에 상태를 저장 및 복원하는 OS 코드를 실행하는 데 시간이 소비
  • 캐시 미스 (Cache miss)
    문맥 교환 발생 시 CPU 캐시 메모리에 들어있던 이전 프로세스의 데이터는 더 이상 필요 없어짐
    새로운 프로세스의 데이터를 위해 캐시를 비우거나 새로운 데이터를 로드하는 과정에서 캐시 미스 발생 확률이 높아짐


4. 스레드 (Thread)

스레드란?

프로세스 내에서 실행되는 흐름 단위 (경량 프로세스, Light Weight Process)

CPU가 실제로 작업을 처리하는 최소 단위

  • 프로세스가 OS로부터 자원을 할당받는 작업의 큰 단위라면
  • 스레드는 해당 자원을 활용하여 실제 명령어를 실행하는 작은 단위
  • 하나의 프로세스는 최소 하나의 스레드(메인 스레드)를 가지며
    필요에 따라 여러 스레드 (멀티스레드)를 가질 수 있음

스레드 자원 (공유 & 독립)

[스레드 간 공유 자원 ]

하나의 프로세스에 속한 모든 스레드는 다음 자원을 공유 함

  • 코드 영역 (Code/Text Segment): 실행 코드
  • 데이터 영역 (Data Segment): 전역 변수, 정적 변수
  • 힙 영역 (Heap Segment): 동적 할당 메모리 (Java에서 new로 생성하는 객체들이 저장되는 곳)

[스레드별 독립 자원 (고유 문맥)]

각 스레드는 실행 흐름을 유지하고 문맥 교환을 위해 다음 자원을 독립적으로 가짐

  • 프로그램 카운터 (Program Counter, PC): 다음에 실행할 명령어의 주소를 저장하여 실행 순서를 기억
  • 레지스터 집합 (Register Set): CPU의 레지스터 값을 저장
  • 스택 영역 (Stack Segment): 함수 호출 시 생성되는 지역 변수와 복귀 주소 등 독립적인 실행 정보를 저장

멀티 스레드

하나의 프로세스 내에서 여러 개의 실행 흐름(스레드)이 동시에 작업을 수행하는 프로그래밍 기법

프로세스가 가지고 있는 자원(메모리 공간, 파일 등)을 여러 개의 스레드가 공유하면서 작업을 나누어 처리하는 방식

[목적] CPU의 활용도를 높여 시스템의 응답성과 효율성을 향상

  • 하나의 프로세스가 시작되면 기본적으로 하나의 메인 스레드가 생성되며, 개발자의 필요에 따라 추가적으로 스레드를 생성하여 작업의 병행 처리 가능

0개의 댓글