Condition Variable

조건 변수와 공유 상태

notify는 이벤트를 저장하지 않는다. wait는 깨어난 뒤에도 predicate를 다시 확인해야 하며, 그 predicate는 mutex로 보호된 상태여야 한다.

01

조건을 변수로 둔다

queue가 비어 있지 않다, stopped가 true다 같은 검사가 가능한 상태가 필요하다.

02

같은 잠금으로 다룬다

조건을 바꾸는 코드와 조건을 기다리는 코드가 같은 mutex를 사용해야 race가 줄어든다.

03

predicate wait를 쓴다

가짜 깨움이나 먼저 온 알림 때문에 깨어나도 조건이 참인지 다시 확인한다.

unique_lock
wait 제어 wait가 잠금을 풀고 다시 잡아야 하므로 lock_guard로는 부족하다.
조건 변수와 짝이다.
notify_one
대기자 하나 작업 하나가 생긴 생산자-소비자 구조에 맞다.
상태 변경 뒤 호출한다.
notify_all
전체 깨움 종료 플래그처럼 모두가 다시 봐야 할 조건에 사용한다.
불필요한 깨어남이 생길 수 있다.
spurious
가짜 깨움 알림 없이도 wait가 돌아올 수 있다.
predicate가 방어한다.

상태 변경 · 동일 mutex · 종료 조건 점검

상태 변경 notify 전에 실제 predicate 상태가 바뀌는가.
동일 mutex 조건을 읽고 쓰는 모든 경로가 같은 mutex를 사용하는가.
종료 조건 대기 스레드가 프로그램 종료 시 빠져나올 방법이 있는가.

predicate wait

std::unique_lock lock(m);
cv.wait(lock, [&] { return stopped || !jobs.empty(); });
if (stopped && jobs.empty()) return;