Для того, чтобы вы знали, что происходит, «узкий цикл» потребляет выделение ЦП вашего потока, как и любой другой код, выполняемый вашим потоком.Разница лишь в том, что это ничего не дает.Ну, я думаю, что согревать ядро - это что-то ... Вы, вероятно, никогда не захотите этого делать, если вы не заботитесь о стоимости переключения контекста, и вы точно не знаете , что время ожидания будет намного корочечем временной интервал вашей нити, который составляет около 1 мс.Я не знаю, является ли сон таким же плохим, как yield (AFAIK yield устанавливает ваш поток в конце списка потоков для активации на вашем уровне приоритета), но оба по крайней мере несут штраф за переключение контекста.Существует стоимость переключения контекста.Переключение контекста - это то, что происходит, когда заканчивается временной поток вашего потока.Он может либо закончиться, потому что вы завершили его с помощью yield или sleep, либо если ядро завершило его, опередив вас.Прочтите о SMP и спин-блокировках, чтобы больше узнать о переключениях контекста и случаях, когда применяется замкнутый цикл.
Кроме того, когда вы спите, вы точно не знаете, когда снова проснетесь.поэтому одна из причин, по которой вы не хотите спать, это то, что вам нужно что-то сделать быстро.Вы можете подождать пару мс, прежде чем их перенести.
Все остальные дали вам решение pthread_cond_wait, которое требует блокировки через мьютексы и выглядит просто и понятно.Производительность может быть адекватной вашим потребностям, но относительно медленной по сравнению с решением, использующим сигналы ( sigwait и pthread_kill ).Сложность подкрадется к вам.
Здесь не обсуждается, почему вы блокируете мьютекс перед тестированием, если вам нужно дождаться выполнения условия.Причина в том, что у такого кода есть недостаток:
while (x <= y) {
pthread_cond_wait(&cond, &mut);
}
Ваш поток может протестировать (X <= Y), увидеть, что он должен ждать, но быть предварительно извлеченным, прежде чем он присоединится к условиюзначение.Другой поток, который только что изменил x или y, сигнализирует об условии в этом временном интервале, прежде чем первый поток присоединится к условию.Таким образом, сигнал состояния теряется.Таким образом, в конечном итоге, везде, где вы изменяете переменные, влияющие на сигнал, вы должны добавлять блокировки.</p>
pthread_mutex_lock(&mut);
/* modify x and y */
if (x > y) pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mut);
Это может означать, что вы добавляете эти блокировки мьютекса во многих разных местах, и ваш код становится более сложным и медленным из-за этого.Возможность зависания потока в ожидании условия всегда есть.У решения loop, test, sleep нет ни одной из этих проблем.Таким образом, если известно, что время ожидания короткое, использование сна в цикле, вероятно, является хорошим решением.Особенно, если вы можете спать на секунду или больше между тестами.Если можете, то не беспокойтесь о мьютексах и условиях.Если время сна короткое, например, 1 мс, а время ожидания длинное, например, минуты или часы, то вы в конечном итоге будете тратить некоторые ресурсы, постоянно просыпаясь и возвращаясь ко сну.Вы должны судить.
Также имейте в виду, что иногда ядро будет пытаться разбудить поток официанта немедленно, а в других случаях будет задержка.Если поток просыпается слишком рано, он проснется, пока мьютекс заблокирован, и сразу же вернется в режим сна, пока мьютекс не разблокируется.Если это становится проблемой, сообщите об этом состоянии следующим образом:
pthread_mutex_lock(&mut);
/* modify x and y */
if (x > y) {
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cond);
} else
pthread_mutex_unlock(&mut);
Спасибо пользователю user576875, чьи примеры кода я скопировал.