프로그램과 프로세스
프로세스와 스레드 이전에 프로그램과 프로세스는 어떤 차이가 있는지 알아보자.
위키백과에서 소개하는 프로그램과 프로세스의 정의는 다음과 같다.
프로그램: 컴퓨터 프로그램이란 컴퓨터가 실행하도록 프로그래밍 언어로 작성된 수열 또는 명령어 세트
프로세스: 컴퓨터에서 연속적으로 실행되고 있는 프로그램
즉 프로그램은 컴퓨터에서 실행 할 수 있는 파일을 통칭하는데, 파일을 실행하지 않은 정적인 상태를 의미하고, 프로세스는 실행되고 있는 프로그램의 동적인 상태를 의미한다.
작업 관리자를 켜서 실행중인 프로그램인 프로세스의 상태를 확인할 수 있다.

프로그램과 프로세스의 구성
그렇다면 프로그램은 어떻게 구성되어 있을까?
프로그램은 Code 영역과 Data 영역으로 구성 되어있다.
- Code(Text) 영역: CPU가 실행할 기계어 명령어(컴파일 된 실행 가능한 코드 덩어리)가 들어간다.
- Data 영역: 전역 변수나 정적(static) 변수 등 프로그램이 시작될 때부터 종료될 때까지 유지되는 데이터가 담긴다.
- Initialized Data: 초기값이 있는 변수.
- Uninitialized Data (BSS): 초기값이 없는 변수.
여기서 프로그램이 실행되어 메모리에 로드가 되면 동적 영역인 Heap 영역과 Stack 영역을 할당받으며 프로세스라는 이름으로 불리게 된다.

- Stack 영역: 임시 데이터가 저장되는 곳. 컴파일 타임에 크기가 결정되고, 실행 시에 데이터가 쌓이는데 최대 크기를 초과하게 되면 stack overflow 에러가 발생한다.
- Heap 영역: 동적으로 할당되는 데이터가 저장되는 곳으로 런타임에 크기가 결정된다.
프로세스의 생명 주기
프로세스의 생명 주기는 다음과 같다.

프로세스의 상태
- New: 프로세스가 메모리에 올라와 실행 준비를 완료한 상태.
- Ready: 프로세스가 CPU를 얻을때까지 기다리는 상태.
- Running: ready상태에 있는 프로세스 중 하나가 CPU를 얻어 실제 작업을 실행하는 상태.
- Waiting: 실행 상태에 있는 프로세스가 입출력을 요청하면 입출력이 완료될 때까지 기다리는 상태.
- Terminated: 프로세스가 종료되는 상태.
프로세스의 전이과정
- Dispatch(): 준비 상태의 프로세스 중 하나를 선정하여 CPU를 할당함.
- Interrupt(): 할당된 시간이 초과(Timeout)되거나 우선순위에 밀려 CPU를 양도하고 준비 상태로 전환함.
- Block(): I/O 요청 등 자원 할당을 기다리기 위해 실행 상태에서 대기(Waiting) 상태로 전환함.
- Wakeup(): 요청한 자원이 할당되어 대기 상태에서 다시 준비(Ready) 상태로 전환함.
PCB(Process Control Block, 프로세스 제어 블록)
- 각각의 프로세스는 자신의 정보 묶음인 PCB를 가지고 있다. PCB에는 프로세스 상태와 PID, 프로그램 카운터, 메모리 한계, 레지스터 정보 등이 담겨있다.
- PCB는 프로세스가 생성될 때 마다 고유의 PCB가 생성되어 메인 메모리에 유지되고(커널 영역에 저장), 프로세스가 완료되면 제거된다.
- 프로그램 실행 → 프로세스 생성 → 프로세스 주소공간 생성 → 메타데이터 PCB에 저장
- CPU는 프로세스의 상태에 따라서 교체 작업이 이루어지기 때문에 교체되는 프로세스의 상태 값을 PCB에 저장해 두었다가 다시 수행할 때 사용한다.

PCB의 상세구조
- Process state: 프로세스의 상태
- Program Counter: 해당 프로세스가 이어서 실행해야 할 명령의 주소를 가리키는 카운터.
- CPU register: 프로세스를 실행하기 위해 저장해야 할 레지스터에 대한 정보
- CPU-scheduling information: CPU 스케줄러에 의해 중단된 시간 등의 정보
- Memory-management information: base, limit 레지스터 값 등의 메모리 시스템 정보
- Accounting information: 사용된 CPU 총량, 프로세스 개수, 시간제한 등의 계정 정보
- I/O status information: 프로세스에 할당된 I/O 디바이스 목록
스레드
위키 백과에서 정의한 스레드의 개념은 다음과 같다.
어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있다.
여기서 말하는 실행되는 흐름의 단위란 정확히 어떤것을 의미하는 걸까?
크롬은 멀티 프로세스 구조를 채택하기 때문에, 각각의 탭은 기본적으로 개별적인 프로세스로 동작한다. 하나의 탭에서는 화면을 렌더링하거나 서버와의 통신으로 데이터를 받아오는 등의 여러 작업의 실행이 동시에 일어나게 되는데 이러한 각각의 실행 흐름을 스레드라고 한다.
스레드의 특징
스레드는 프로세스 내에서 실행되는데 하나의 프로세스에 여러개의 스레드가 존재한다면, 각각의 스레드는 속해있는 프로세스의 자원을 공유하여 사용한다.
대부분의 영역을 공유하며 사용하지만, Stack 영역은 독립적으로 구분된다. 동적으로 생성되는 Heap과 Stack 영역에서, Heap 영역에는 프로세스 내에서 동적으로 할당된 객체나 인스턴스가 저장되며 모든 스레드가 이를 공유하여 효율적으로 데이터를 주고받는다. 반면, Stack 영역은 스레드마다 독립적인 함수 호출 기록을 유지함으로써 각 스레드가 서로의 실행 흐름을 방해하지 않고 독립적으로 동작할 수 있게 한다.

| 프로세스 (Process) | 스레드 (Thread) |
| 운영체제로부터 자원을 할당받는 작업 단위 | 프로세스가 할당받은 자원을 이용하는 실행 단위 |
| 독립적 (자원 공유 X) | 프로세스 내 자원 공유 |
| 오류 발생 시 타 프로세스에 영향 없음 | 오류 발생 시 프로세스 전체에 영향을 줄 수 있음 |
스레드의 생명주기
스레드의 생명주기는 다음과 같다.

스레드의 상태
- New: 스레드가 생성된 상태로 아직 start() 메소드가 호출되지 않은 상태.
- Runnable: start() 메소드가 호출되어 실행 대기 중인 상태.
- Running: CPU를 점유하여 실제로 코드를 실행하고 있는 상태.
- Waiting: 일시 정지 상태로, 다른 스레드의 통지를 기다림.
- Times Waiting: 주어진 시간 동안 일시 정지 상태로 대기.
- Block: 다른 스레드가 사용하고 있는 객체의 lock이 풀릴 때까지 대기.
- Terminated: 실행을 완료한 후 종료된 상태.
스레드의 전이과정
- start(): 스레드를 생성하고 실행 대기(Runnable) 상태로 전환함.
- run(): 스레드가 실행할 핵심 로직을 수행함.
- yield(): 실행 중인 스레드가 동일 우선순위의 다른 스레드에게 실행 기회를 양보함.
- sleep(): 지정된 시간 동안 현재 스레드를 일시 정지 상태로 만듦.
- wait(): 동기화된 블록 내에서 스레드를 일시 정지(Waiting) 상태로 전환함.
- notify(): wait()로 인해 대기 중인 스레드 하나를 실행 대기 상태로 전환함.
- notifyAll(): wait()로 대기 중인 모든 스레드를 실행 대기 상태로 전환함.
참고문헌
도서
- 면접을 위한 CS 전공 지식 노트
블로그
- Inpa Dev - 완전히 정복하는 프로세스 vs 스레드 개념
- Bible, Lee, Data - [Java] 프로세스와 스레드: 컴퓨터의 작업 처리 단위
- SungBum Park - [운영체제(OS)] 5.프로세스 관리