📌 임계 구역(Critical Section)
임계 구역은 둘 이상의 프로세스나 스레드가 동시에 접근하면 문제가 발생할 수 있는 공유 자원에 접근하는 코드 영역이다.
즉, 동시에 실행되는 프로세스나 스레드가 동시에 임계구역에 진입하여 실행되면 문제가 발생할 수 있다.

프로세스 A가 공유 메모리를 쓰고, 프로세스 B가 같은 메모리를 동시에 읽으려는 경우, 아직 쓰기가 완료되지 않았기 때문에 잘못된 값을 읽을 수 있음 → 문제 발생
즉, 프로세스A의 공유메모리 공간에 데이터를 쓰는 코드와 프로세스 B의 공유 메모리 공간을 읽는 코드는 임계 구역이 된다.
➡️ 첫번째 경우문제가 되지 않지만 순서가 바뀔 경우 문제가 되는 구간이기 때문에 이 구간(코드를) 임계 구역이라고 한다.
이러한 것처럼 동시에 실행되는 프로세스 혹은 스레드를 다룰 때는 언제나 임계 구역을 동시에 실행하지 않도록 주의해야 한다.
따라서 임계 구역에는 하나의 프로세스/스레드만 진입해야 한다.
만약 프로세스와 스레드가 동시에 임계 구역의 코드를 실행하여 문제가 발생하는 상황이 생긴다면 이를 레이스 컨디션이라고 한다.
📌 레이스 컨디션(Race Condition)
- 임계 구역을 동시에 여러 프로세스나 스레드가 실행해 의도치 않은 결과나 충돌이 발생하는 상황
- 레이스 컨디션 발생 시 → 데이터의 일관성 손상
레이스 컨디션이 발생한다면 자원의 일관성이 손상될 수 있기 때문에 2개 이상의 프로세스 혹은 스레드가 임계 영역에 진입하고자 한다면 둘 중 하나는 작업이 끝날 때까지 대기해야 한다.
✅ 레이스 컨디션을 방지하려면 어떻게 해야될까??
임계 구역을 관리하기 위해서는 프로세스와 스레드가 동기화되어야 한다. 동기화 조건은 다음과 같은 2가지 조건을 만족해야 한다.
- 실행 순서 제어 : 프로세스 및 스레드를 특정 순서대로 실행되어야 할 코드 흐름 보장
- 상호배제 : 동시에 접근해서는 안되는 자원에 하나의 프로세스 및 스레드만 접근하기
📌 동기화 기법
실행 순서 제어와 상호 배제를 보장하기 위한 동기화 기법은 뭐가 있을까
1. 뮤텍스 락(Mutex Lock)
하나의 자원에 대한 접근을 제어할 때 사용
임계 구역에 접근하고자 한다면 반드시 락을 획득해야 하고, 임계 구역에서의 작업이 끝났다면 락을 해제해야 한다.
뮤텍스 락은 프로세스 및 스레드가 공유하는 변수(lock)과 2개의 함수 (acquire, release)로 구현된다.
- lock(공유 변수) : 프로세스 및 스레드가 공유하는 변수가 뮤텍스 락의 역할 을 수행한다.
- acquire() : 락을 획득하기 위한 함수로, 특정 락에 대해 한 번만 호출이 가능한 함수이다.
- release() : 획득한 락을 해제하기 위한 함수이다.
1. 우선 임계 구역에 진입하려면 프로세스 및 스레드가 공유하는 락을 획득하는 과정이 선행되어야 하므로 lock.acquire()를 호출
=> 이때 다른 프로세스 및 스레드가 lock.acquire()을 호출해도 락을 획득할 수 없다. 오롯이 락이 해제될 때까지 기다려야 한다.
2. 임계 구역의 작업이 끝나면 락을 해제하기 위해 lock.release()를 호출한다.
만약 임계 구역 앞에서 대기하는 프로세스 혹은 스레드가 있었다면 그때 lock.acquire() 호출에 성공하고 임계 구역에 진입하게 된다.
2. 세마포(Semaphore)
여러 개의 자원을 제어할 수 있는 동기화 도구
세마포는 뮤텍스 락과 비슷하지만, 세마포를 이용하면 공유 자원이 여러개 있는 상황에서도 동기화가 가능하다.
하나의 변수와 2개의 함수로 구성된다.
- 변수S : 사용 가능한 공유 자원의 개수를 나타내는 변수 -> 공유 자원의 수
- wait() : 임계 구역 진입 시 호출하는 함수
- signal(): 임계 구역 종료 후 호출하는 함수
이때 사용 가능한 공유 자원의 개수는 임계 구역에 진입할 수 있는 프로세스의 개수와 같다.
공유 자원의 개수가 S개일 경우, 임계 구역에 진입하여 동시에 실행 가능한 프로세스 혹은 스레드도 S개 이다.
그리고 세마포를 이용할 때 임계 구역 진입 전후로 wait() 과 signal()함수를 호출하여 사용한다.
wait()
//임계 구역
signal()
wait() 함수
wait(){
S--;
if( S < 0 ){
sleep();
}
}
1. 사용 가능한 공유 자원의 개수를 나타내는 변수 S를 1감소시킨다.
2. 변수 S의 값이 0보다 작은지 여부를 확인
감소 시켰을 때 0 이상이라는 것은 사용 가능한 공유 자원의 개수가 남아 있었음을 의미 => wait()을 호출한 프로세스 및 스레드는 임계 구역 진입
반대로 감소 시켰을 때 S가 0미만이다? 가능한 공유 자원의 개수가 남아 있지 않았음을 의미. => 변수 S의 값이 0보다 작으면 wait()을 호출한 프로세스 및 스레드는 대기 상태로 전환 되어 임계 구역에 진입할 수 없게 된다.
signal() 함수
sinal(){
S++
if( S <= 0 ){
wakeup(p)
}
}
임계 구역에서의 작업이 끝난 프로세스 및 스레드가 호출한다.
wait()과 반대로 동작함으로 동작 과정 생략

3. 조건 변수(Condition Variable)
실행 순서를 제어하기 위한 동기화 도구로, 특정 조건 하에 프로세스를 실행/일시 중단함으로써 프로세스나 스레드의 실행 순서를 제어할 수 있다. 조건 변수에 대해 wait()과 signal()함수를 호출할 수 있다.
- 아직 특정 프로세스가 실행될 조건이 되지 않았을 때는 wait()을 통해 실행을 중단한다.
- 특정 프로세스가 실행될 조건이 충족되었을 때는 signal()을 통해 실행을 재개한다.
3. 모니터(Monitor)
공유 자원 + 그 자원을 다루는 연산을 하나의 단위로 구성
공유 자원과 그 공유 자원을 다루는 함수로 구성된 동기화 도구로 상호 배제를 의한 동기화뿐만 아니라 실행 순서 제어를 위한 동기화까지 가능하다.
모니터의 작동 원리
프로세스 및 스레드는 공유 자원에 접근하기 위해 반드시 정해진 공유 자원 연산을 통해 모니터 내로 진입해야 하고, 모니터 안에 진입하여 실행되는 프로세스 및 스레드는 항상 하나여야 한다.
이미 모니터 내로 진입하여 실행 중인 프로세스 및 스레드가 있다면 큐에서 대기해야 한다.
=> 큐를 사용하여 진입 순서를 제어 → 상호 배제 + 실행 순서 제어
스레드 안전
멀티스레드 환경에서 어떤 변수나 함수 , 객체에 동시 접근이 이루어져도 실행에 문제가 발생하지 않는 상태를 의미한다.
레이스 컨디션이 발생했다 ? ➡️ 스레드 안전하지 않는 상황이다.
스레드 안전하다 ➡️ 여러 스레드에 의해 호출되어도 레이스 컨디션이 발생하지 않는 것을 의미한다.
📌 교착 상태(Deadlock)
서로 자원을 기다리며 무한 대기하는 상태, 일어나지 않을 사건을 기다리며 프로세스의 진행이 멈춰 버리는 현상을 말한다.
교착 상태의 발생 조건 4가지
하나라도 만족하지 않는다면 교착 상태는 발생하지 않는다. 4개의 조건이 모두 만족할 때 교착 상태가 발생할 가능성이 생긴다.
- 상호 배제
한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없는 상황 - 점유와 대기
한 프로세스가 어떤 자원을 할당받은 상태에서 다른 자원을 할당 받기를 기다린다면 교착 상태가 발생할 수 있다. - 비선점
자원이 비선점되었다는 말은 해당 자원을 이용하는 프로세스의 작업이 끝나야만 비로소 자원을 이용할 수 있다는 것을 의미한다.
즉, 어떤 프로세스도 다른 프로세스의 자원을 강제로 빼앗지 못하는 경우 교착 상태가 발생할 수 있다. - 원형 대기
프로세스와 프로세스가 요청한 자원이 원의 형태를 이루는 경우이다.
아래 와 같이 프로세스가 서로 점유한 자원을 할당받기 위해 원의 형태로 대기할 경우 교착상태가 발생한다.

교착 상태 해결 방법
- 교착 상태 예방
교착 상태를 발생시키는 4가지 필요 조건 중 하나를 충족하지 못하게 하는 방법이다. - 교착 상태 회피
교착 상태가 발생하지 않을 정도로만 조심하면서 할당하는 방법이다. - 교착 상태 검출 후 회복
교착 상태의 발생을 인정하고 처리하는 사후 조치이다.
운영체제는 프로세스가 자원을 요구할 때마다 자원을 할당해주고, 주기적으로 교착상태의 발생 여부를 검사한다.
그러다 교착 상태가 검충되면 프로세스를 자원 선점을 통해 회복 시키거나, 교착 상태에 놓인 프로세스를 강제 종료함으로써 회복시킬 수 있다.
[OSTEP 운영체제 정리] - Concurrency Problem
비 교착 상태 오류원자성 위반 오류( atomicity violation )다수의 메모리 참조 연산들 간에 있어 예상했던 직렬성이 보장되지 않았다. 즉, 코드의 일부에 원자성이 요구되었으나, 실행 시에 그 원자성
soco.tistory.com
https://product.kyobobook.co.kr/detail/S000214014967
이것이 취업을 위한 컴퓨터 과학이다 with CS 기술 면접 | 강민철 - 교보문고
이것이 취업을 위한 컴퓨터 과학이다 with CS 기술 면접 | 기술 면접과 실무에 필요한 CS 지식, 한 권으로 끝내자!프로그램의 실행 원리를 이해하지 못한 채 ‘일단 작동만 하도록 만드는 것’과 정
product.kyobobook.co.kr
'Computer Science' 카테고리의 다른 글
| [CS]CPU는 어떻게 메모리에 적재된 프로세스의 주소를 인식하고 관리할까? (0) | 2025.04.27 |
|---|---|
| [CS]CPU스케줄링 (0) | 2025.04.18 |
| [CS]프로세스와 스레드 (0) | 2025.04.18 |
| 운영체제를 알아보자 (2) | 2025.03.31 |
| [OSTEP 운영체제 정리] - Log-Structured File System (0) | 2024.06.24 |