实现忙循环的最佳方法是什么?

时间:2011-10-01 12:36:49

标签: c linux

实现繁忙循环的最佳方法是什么?如果我错了,请纠正我?

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

4 个答案:

答案 0 :(得分:7)

要进行无限等待,对于信号(还有什么),有pause()系统调用。你必须把它放在一个循环中,因为每次传递信号时它都会返回(总是带-1并且errno设置为EINTR):

while (1)
    pause();

作为一个奇怪的说明,这就是AFAIK记录到总是失败的唯一POSIX功能。

更新:感谢dmckee,在下面的评论中,sigsuspend()也始终失败。它与pause()完全相同,但它更符合信号。不同之处在于它具有参数,因此除了EFAULT之外,它还会失败EINTR

答案 1 :(得分:3)

繁忙的循环是永远不会阻塞并持续检查某些条件的循环。小睡眠足以避免100%的CPU使用率 实现忙等待的最佳方法是不实现它。而不是它,你可以使用阻塞调用或回调。

答案 2 :(得分:2)

Linux已经有了(POSIX 1.g) pselect 一段时间了。如果您正在使用信号处理程序或用户定义的信号,我认为这值得研究。它还解决了其他方法中出现的一些微妙的竞争条件。

我知道你提到了'忙碌循环',但我认为'阻塞循环'是你所追求的。

答案 3 :(得分:0)

如何防止数据依赖关系对其进行优化

首先,当然,只有在您有充分的理由不使用非忙碌循环时才应使用忙碌循环,非忙碌循环通常更有效,请参见:https://codereview.stackexchange.com/questions/42506/using-a-for-loop-or-sleeping-to-wait-for-short-intervals-of-time

现在,如果您只写以下内容,则仅关注繁忙的循环:

while (1);

或:

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

然后可以按照Are compilers allowed to eliminate infinite loops?

所述对这两个参数进行优化

由于这个原因,正如在How to prevent GCC from optimizing out a busy wait loop?中详细解释的那样,我将它们写为:

while (1) asm("");

或:

for (unsigned i = 0; i < 100; i++) {
    __asm__ __volatile__ ("" : "+g" (i) : :);
}
相关问题