학습 목표
Producer-Consumer 문제에서 빈 슬롯·채운 슬롯 세마포어와 뮤텍스 역할을 설명할 수 있다.
Readers-Writers 문제에서 읽기 공유·쓰기 배타 요구를 설명할 수 있다.
고전 패턴이 실무 큐·캐시·connection pool 과 어떻게 대응되는지 설명할 수 있다.
패턴별로 어떤 동기화 primitive를 쓰는지 선택할 수 있다.
문제 상황
- 로그 수집기가 버퍼가 가득인데도 계속 쓰거나, 소비자가 빈 큐에서 pop한다
- 생산·소비 속도 차이를 경계 있는 버퍼로 흡수해야 한다
- 설정 파일은 여러 goroutine이 동시에 읽어도 되는데, 한 번에 하나만 저장해야 한다
- 읽기·쓰기에 다른 잠금 규칙이 필요하다
- 뮤텍스·세마포어 문법은 알지만 어디에 무엇을 걸지 모른다
- 고전 사례가 템플릿이 된다
BlockingQueue·sync.RWMutex가 OS 교재의 어떤 그림과 같은지 연결이 안 된다
동기화 도구와 데드락을 봤다. 이번 편은 도구를 어디에 쓰는지 — 대표 패턴으로 정리한다.
1. Producer-Consumer (생산자-소비자)
생산자는 아이템을 만들어 버퍼에 넣고, 소비자는 꺼내 처리한다. 버퍼 크기는 유한(bounded buffer).

| 동기화 | 역할 |
|---|---|
mutex |
버퍼 구조(in/out 인덱스) 배타 접근 |
empty (세마포어) |
빈 슬롯 개수 — 생산 전 wait |
full (세마포어) |
채운 슬롯 개수 — 소비 전 wait |
생산자 의사코드:
while (true) {
produce item
wait(empty)
wait(mutex)
add item to buffer
signal(mutex)
signal(full)
}
소비자는 wait(full) → wait(mutex) → 제거 → signal(mutex) → signal(empty) 순서.
- 실무:
BlockingQueue, Kafka consumer lag, channel(goroutine),ArrayBlockingQueue wait순서: 뮤텍스 전에 세마포어를 기다리면 데드락 위험 줄임 (빈 슬롯 없으면 mutex 안 잡음)
2. Readers-Writers (독자-저자)
Reader는 동시에 여러 개 가능, Writer는 배타적 — 쓰는 동안 읽기·쓰기 모두 불가.

첫 번째 Readers-Writers (Reader 우선)
| 변수 | 역할 |
|---|---|
read_count |
현재 읽는 reader 수 |
mutex |
read_count 갱신 보호 |
rw_mutex |
writer 진입 배제 |
Reader: read_count++가 1이면 rw_mutex 획득 → 읽기 → read_count--가 0이면 rw_mutex 해제.
Writer: rw_mutex 획득 → 쓰기 → 해제.
- 문제: reader가 계속 오면 writer starvation
Writer 우선·공정 버전
- Writer 우선: 대기 writer가 있으면 새 reader 차단
- 공정: 큐(FIFO)로 reader·writer 순서 보장 —
std::shared_mutex, JavaReadWriteLock구현에 가깝다
실무 대응
| 패턴 | 예 |
|---|---|
| 다중 reader | 설정 캐시, feature flag 조회 |
| 단일 writer | 설정 저장, 스냅샷 갱신 |
| API | DB 읽기 복제본 + 쓰기 마스터 (물리적 분리) |
3. Dining Philosophers (식사하는 철학자) — 개요
5명이 원탁, 젓가락 5개 — 식사하려면 양쪽 젓가락 필요.

- 둘 다 잡는 순서가 순환이면 데드락 (앞서 본 순환 대기)
- 해법: 젓가락 전역 순서, 홀수·짝수 다른 순서, 세마포어로 동시 식사자 수 제한
교과서에서 데드락·동기화 복합 예제로 자주 나온다. 실무에서는 두 리소스를 동시에 잡는 패턴(DB 두 테이블 락, 분산 락 2개)에 대응한다.
4. 패턴 선택 요약
| 패턴 | 핵심 제약 | 주요 primitive |
|---|---|---|
| Producer-Consumer | 버퍼 크기·생산/소비 속도 | 2 세마포어 + mutex |
| Readers-Writers | 읽기 공유, 쓰기 배타 | rw_mutex, read_count, (공정 큐) |
| Bounded parallel work | 동시 실행 수 N | counting semaphore, worker pool |
| Single-flight | 같은 key 한 번만 계산 | mutex + map, `sync.Singleflight` |
5. 정리
- Producer-Consumer: empty/full 세마포어로 슬롯 수, mutex로 버퍼 무결성
- Readers-Writers: reader 병렬·writer 배타, 우선순위에 따라 starvation 트레이드오프
- 고전 패턴은 큐·캐시·RWLock의 설계 언어
- 다음: 물리 메모리를 프로세스에 나눠 주는 방식 — 메모리 관리
다음에 다룰 것
- 메모리 관리 기초
- 연속 할당, 단편화, 페이징 개요
해당 내용은 Operating System Concepts, 10/E (Avraham Silberschatz, Peter Baer Galvin, Greg Gagne) 의 내용을 기반으로 합니다.