Они не совсем мьютексы с дополнительной магией, хотя в некоторых абстракциях (монитор используется в java и C #) переменная условия и мьютекс объединяются в одну единицу. Цель условных переменных - избежать ожидания ожидания / опроса и намека на время выполнения, какой поток (ы) должен быть запланирован «следующим». Подумайте, как бы вы написали этот пример без условных переменных.
while(1) {
lock(mymutex)
if( somevalue != 0)
break;
unlock(mymutex);
}
if( somevalue == 0xdeadbeef )
myfunc();
Вы будете сидеть в узкой петле в этой ветке, сжигая много процессора и создавая много конфликтов на блокировку. Если блокировка / разблокировка мьютекса достаточно дешевая, вы можете оказаться в ситуации, когда другой поток даже не имеет возможности получить блокировку (хотя мьютексы реального мира обычно различают владелец потока и наличие блокировки, а также понятия справедливости так что вряд ли это произойдет в реальности).
Вы можете уменьшить занятость ожидания, вставая в сон,
while(1) {
lock(mymutex)
if( somevalue != 0)
break;
unlock(mymutex);
sleep(1); // let some other thread do work
}
но как долго это хорошее время для сна? Вы просто будете угадывать. Время выполнения также не может сказать, почему вы спите или чего вы ждете. Переменная условия позволяет хотя бы в некоторой степени времени выполнения знать, какие потоки заинтересованы в том же событии в настоящее время.