포스트

임베디드 스터디 - 모니터(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 라이센스를 따릅니다.