Лучший способ реализовать занятый цикл?

Каков наилучший способ реализации занятого цикла? поправь меня если я не прав?

while (1); // obviously eats CPU. 
while (1) { sleep(100); } // Not sure if it is the correct way ?

3 ответа

Решение

Чтобы сделать бесконечное ожидание, для сигнала (что еще) есть pause() системный вызов. Вы должны будете поместить его в цикл, поскольку он возвращает (всегда с -1 и errno установлен в EINTR) каждый раз, когда сигнал доставляется:

while (1)
    pause();

Любопытно, что AFAIK - единственная документально подтвержденная функция POSIX, которая всегда дает сбой.

ОБНОВЛЕНИЕ: благодаря dmckee, в комментариях ниже, sigsuspend() и всегда терпит неудачу. Это так же, как pause(), но это более благоприятно для сигнала. Разница в том, что у него есть параметры, поэтому он может потерпеть неудачу с EFAULT в дополнение к EINTR,

Занятый цикл - это цикл, который никогда не блокирует и постоянно проверяет некоторые условия. Малый сон достаточно хорош, чтобы избежать 100% использования процессора.
Лучший способ реализовать занятое ожидание - не реализовывать его. Вместо этого вы можете использовать блокировку вызовов или обратных вызовов.

В Linux уже давно есть pselect (POSIX 1.g). Если вы используете обработчики сигналов или определяемые пользователем сигналы, я думаю, что это стоит изучить. В нем также рассматриваются некоторые тонкие расовые условия, которые проявляются в других подходах.

Я знаю, что вы упомянули "занятую петлю", но я думаю, что вам нужна "блокирующая петля".

Как предотвратить его оптимизацию за счет зависимостей данных

Во-первых, конечно, вам следует использовать занятые циклы только в том случае, если у вас есть веская причина не использовать незанятые циклы, которые, как правило, более эффективны, см. Https://codereview.stackexchange.com/questions/42506/using-a- для цикла или сна для ожидания коротких интервалов времени

Теперь, сосредоточившись только на занятых циклах, если вы просто напишете что-то вроде:

while (1);

или:

for (unsigned i = 0; i < 100; i++);

тогда оба из них могут быть оптимизированы, как указано в: Разрешено ли компиляторам исключать бесконечные циклы?

По этой причине, как подробно описано в разделе: Как предотвратить оптимизацию GCC цикла ожидания занятости? Я бы написал их как:

while (1) asm("");

или:

for (unsigned i = 0; i < 100; i++) {
    __asm__ __volatile__ ("" : "+g" (i) : :);
}
Другие вопросы по тегам