Почему мы используем мьютекс здесь, когда мы используем условную переменную?
Основы условной переменной требуют блокировки для корректной работы.
Только поток с блокировкой должен пытаться изменить состояние переменной условия (т. Е. Путем вызова одной из функций переменной условия (это также защищает объект, над которым вы действительно работаете)).
В функции customer () в цикле while мы берем мьютекс и ожидаем условия, как функция-производитель может заблокировать мьютекс, если потребитель уже взял его
Когда вы вызываете wait () для условной переменной, поток переводится в спящий режим, а мьютекс освобождается. Когда поток проснулся, он должен повторно получить блокировку, прежде чем функция wait () вернется к пользовательскому коду.
и как он может сообщить, что не тупик?
Он не блокируется, потому что wait () снимает блокировку перед переводом потока в спящий режим.
Чем unique_lock отличается от scoped_lock?
В этом контексте нет. Но если у вас есть какая-либо конкретная реализация, укажите ее реализацию, и мы можем обсудить ее более подробно.