while(true)无限循环会导致CPU占用过高吗?

3

我有一个情况,需要在服务中运行一个不停的循环,每次检查特定的条件,然后根据情况采取相应的行动。从设计的角度来看,使用 while (true) 循环非常适合:

while (true)
{
    Process();
}

Process() 方法检查内存中(快速)的数据存储状态。如果它发现基于状态有工作要做,它将使用 Task.Run() 进行处理(因此控制立即返回到循环中)。

我看到一些参考资料指出这样会占用不必要的 CPU 循环,建议使用 Timer 或在循环中添加 Thread.Sleep。我也看到有帖子说明使用 while (true) 没有问题。

在我的开发机上,似乎没有负面影响,虽然 CPU 使用率确实会增加。可能是因为 CPU 使用率分布在多个核心上,而部署环境可能只有一个单核心。

while (true) 循环对 CPU 有负面性能影响吗?如果有,有什么正确的缓解方式?


while(true) { Task.Run(..) }会导致CPU占用率过高。请查看生产者消费者模式和发布订阅模式,了解如何正确处理此问题。 - Aron
2个回答

5
当然,这要看你在做什么

while(true)循环本身并不会导致性能下降。性能问题出现在方法体中,比如这里的Process()

如果该方法旨在永远运行而且永远不停歇,那么使用此结构是可以的。但是,如果Process应该响应事件或“监听”某些操作,则将其放入while(true)循环中会导致处理器不必要地轮询。

例如:

while (true)
{
   //At the start of every minute
   if (DateTime.Now.Seconds == 0)
       //Do Something
}

这将是非常糟糕的。你让CPU持续检查一个每分钟只有一次为真的条件,并阻止CPU在其余时间内执行有用的工作。

在这种情况下,最好使用Threading命名空间中可用的一些功能来释放CPU。


4
在合作式多任务系统中,这确实会使CPU占用率达到100%(或至少一个核心)。
然而,大多数现代操作系统采用抢占式多任务处理,这基本上意味着操作系统控制进程的运行时间。因此,虽然你的循环将使用线程(或可能是进程)的100%时间,并剥夺其他一些CPU时间,但操作系统会确保其他已准备好运行的进程/线程得到运行的机会。最坏的情况下,你的程序可能会变慢一些。
你需要特别注意的一件事是,这样的循环将绑定运行它的线程,使该线程无法用于其他任务。因此,你不应该在UI线程上执行此操作。(有一个Application.DoEvents()方法,但你必须自己每隔一段时间调用它,它的使用表明你正在做一些真正属于其自己线程的任务)。

他们不会完全被饿死,但是在这个进程浪费时间而没有做任何有生产力的事情时,他们将获得比平常更少的CPU时间。 - Servy
@Servy:说得好(已编辑)。这会占用一些本来可以用于其他进程的时间。但是,该进程只能浪费操作系统允许它使用的时间,因此除非有人搞乱了优先级和/或操作系统设计不良,否则它无法独占CPU。 - cHao
正确,它不会完全崩溃整个机器,只会使整个机器变慢。OP并不是在问这样做是否会完全破坏他的整个机器,他在问是否存在负面后果。除了“你的电脑再也不能做任何事情了[插入邪恶的笑声]”之外,还有负面后果。 - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接