unique_lockwait가 내부에서 unlock/relock을 해야 하므로 lock_guard가
아니라 std::unique_lock을 넘깁니다.
조건자 점검cv.wait(lock, [] { return ready; }) 형태로 조건을 코드에
둡니다.
wait조건이 거짓이면 mutex를 원자적으로 풀고 잠들며, 깨어날 때
다시 잠급니다.
notify_one/all생산자는 같은 mutex 아래 공유 상태를 바꾼 뒤 notify_one/all로
깨웁니다.
recheck깨어난 이유가 알림이 아닐 수도 있어 predicate가 참일 때만
진행합니다.