하나의 프로세스는 두 가지 특징을 가진다:
대부분의 현대 운영체제들은 이 두 가지 특성들을 독립적으로 다룬다.
실행 중인 프로그램
프로그램은 디스크 상에 존재하며 실행을 위한 명령어와 정적 데이터의 묶음이다.
운영체제는 프로그램 실행을 위해 다음 단계를 거친다.
쓰레드란, 프로세스 내에서 실행되는 흐름의 단위를 말한다.
실행의 흐름(execution stream)은 stack, register와 밀접한 관련이 있다.

multithreaded process 에서 쓰레드들은 주소 공간을 공유하는 한편, 각자의 레지스터들과 스택을 할당받는다.
✅ Threads의 특징
실행 상태를 가진다 (running, ready, stopped (blocked))
실행되지 않을 때는 쓰레드의 문맥(context)을 저장한다
자신만의 실행 스택을 가진다.
자신이 속한 프로세스의 메모리 주소 공간과 자원에 접근할 수 있다
프로세스의 모든 쓰레드는 이 메모리 및 자원을 공유한다
한 쓰레드가 공용 메모리를 수정하면, 프로세스 내 다른 쓰레드들도 이를 볼 수 있다
한 쓰레드가 연 파일은 다른 쓰레드들도 사용할 수 있다
✅ Multithreaded Process의 장점
⚡ Responsiveness (응답성)
🔗 Resource Sharing (자원 공유)
💸 Economy (경제성)
시간이 덜 든다:
- 새로운 프로세스를 생성하는 것보다 새로운 쓰레드를 생성하는 것이
- 프로세스를 종료하는 것보다 쓰레드를 종료하는 것이
매우 적은 자원만 사용한다.
명령어의 실행 순서에 따라 결과가 달라지는 상황을 경쟁 조건(race condition)이라고 한다.
예를 들어,
counter = counter + 1;
위 코드는 다음과 같은 순서로 실행될 것이다.
mov (counter 변수 주소), %eax
add $0x1, %eax
mov %eax, (counter 변수 주소)
만약, count의 값이 50이고
쓰레드 1이
1. 50을 eax 레지스터에 넣음. eax=50
2. 레지스터의 값에 1을 더하여 eax=51
3. 타이머 인터럽트 발생. 현재 상태를 쓰레드의 TCB에 저장
쓰레드 2가
1. counter 값을 얻어와서 eax에 넣음. eax=50
2. 레지스터의 값에 1을 더하여 eax=51
3. counter에 51 저장
쓰레드 1이 리턴하여 아까 계산한 eax=51을 counter에 저장.
counter를 증가시키는 코드가 두 번 수행이 되었지만 50에서 시작한 counter의 값은 1 증가한 51이다.
✅ 임계 영역(critical section)
공유 자원에 접근하는, 하나 이상의 쓰레드에서 동시에 실행되면 안되는 코드
✅ 경쟁 조건(race condition)
멀티 쓰레드가 거의 동시에 임계 영역을 실행하려고 할 때 발생하며 공유 자료 구조를 모두가 갱신하려고 시도한다면 의도하지 않은 결과를 만든다.
✅ 비결정적(Indeterminate) 프로그램
비결정적 프로그램은 하나 또는 그 이상의 경쟁 조건을 포함하여 그 실행 결과가 각 쓰레드가 실행된 시점에 의존하기 때문에, 프로그램의 결과가 실행할 때마다 다르다.
경쟁을 피하려면, 상호 배제(mutual exclusion)라는 기법을 사용하여서 하나의 쓰레드만이 임계 영역에 진입할 수 있도록 보장해야 한다.