Переменные условия позволяют атомарно освободить удерживаемый мьютекс и перевести поток в режим сна. Затем, получив сигнал, атомно восстанавливают мьютекс и просыпаются. Вы сталкиваетесь с этим, например, в проблеме производителя / потребителя. Вы будете заблокированы, если вы ложитесь спать, удерживая мьютекс, но вы также можете заблокировать его, если отпустите его перед сном (пропустив сигнал пробуждения).
Это не то, что можно объяснить в нескольких параграфах без примеров, и есть несколько известных подводных камней и предостережений при использовании условных переменных. Проверьте "Введение в программирование с помощью потоков" Эндрю Бирреллом.
Независимо от языка, условные переменные всегда принимают мьютекс. Мьютекс должен удерживаться при вызове wait. Вы должны всегда проверять, что желаемое условие все еще выполняется после возвращения из ожидания. Вот почему вы всегда видите условные ожидания, заключенные в цикл while. C ++ 11 также дает вам предикатную перегрузку, которая является синтаксическим сахаром для цикла while.
Мьютекс защищает общее состояние. Условие позволяет блокировать, пока не получит сигнал.
unique_lock
- это оболочка RAII (Resource Acquisition Is Initialization) для блокировки и разблокировки данного мьютекса. Это концептуально идентично выражению lock
в C #. Это упрощает обработку исключений, связывая получение и освобождение мьютекса со временем жизни экземпляра unique_lock
. Я не знаю, есть ли причина, по которой condition_variable
заставляет вас использовать это, кроме того факта, что это хорошая практика. Единственная разница между unique_lock
и lock_guard
заключается в том, что unique_lock
можно разблокировать ... именно поэтому вы должны использовать его вместо lock_guard
с condition_variable
.