임베디드 스터디 - 모니터(Monitor)와 조건변수
임베디드 스터디 - 모니터(Monitor)와 조건변수
모니터(Monitor)란
- 세마포어의 한계 — P()/V()를 프로그래머가 직접 올바른 순서로 배치해야 하며, 실수 시 데드락 또는 상호배제 위반 발생
- 모니터는 이를 해결하기 위한 컴파일러 수준의 고수준 동기화 구조
- 핵심 아이디어: 공유 데이터 + 접근 함수를 하나의 캡슐로 묶고, 함수 진입 시 잠금을 자동화 처리
1
2
3
4
5
6
┌─────────────────── Monitor ───────────────────┐
│ 공유 데이터 (shared variables) │
│ + 초기화 코드 │
│ + 함수1() { ... } ← 한 번에 하나만 실행 가능 │
│ + 함수2() { ... } │
└────────────────────────────────────────────────┘
- 세마포어와의 핵심 차이:
- 세마포어 — 프로그래머가 lock/unlock을 직접 호출
- 모니터 — 함수 진입/퇴장 시 잠금 자동, 조건 불충족 시
cond_wait()으로 대기 선언
조건변수(Condition Variable)
- 모니터 안에 진입했지만 실행 조건이 충족되지 않을 때 사용
cond_wait(cv)— 조건 불충족 시 모니터를 일시 반납 하고 대기 큐에서 잠든다cond_signal(cv)— 대기 큐에서 잠든 스레드 하나를 깨운다
cond_wait()이 모니터를 반납하는 이유
- 반납하지 않으면 — 잠든 스레드가 모니터를 점유한 채 대기하므로 다른 스레드가 진입 자체를 못 하게 됨 → 데드락 발생
생산자-소비자 모니터 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
monitor ProducerConsumer {
int buffer[N];
condition not_full; // 빈 자리가 생길 때까지 대기
condition not_empty; // 데이터가 생길 때까지 대기
void produce(item) {
if (버퍼 가득 참) cond_wait(not_full); // 모니터 반납 후 대기
/* 데이터 삽입 */
cond_signal(not_empty); // 소비자 깨움
}
void consume() {
if (버퍼 비어 있음) cond_wait(not_empty); // 모니터 반납 후 대기
/* 데이터 꺼냄 */
cond_signal(not_full); // 생산자 깨움
}
}
세마포어 vs 모니터 비교
| 항목 | 세마포어 | 모니터 |
|---|---|---|
| 동기화 책임 | 사용자 | 컴파일러 |
| 잘못 사용 시 | 데드락 / 상호배제 위반 | 데드락 |
| 조건 대기 | P()로 직접 블록 | cond_wait() |
| 사용 난이도 | 높음 (단순하지만 위험) | 낮음 (복잡하지만 안전) |
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.