【问题标题】:Does a while(true) Infinite Loop Peg the CPU? [closed]一段时间(真)无限循环是否会占用CPU? [关闭]
【发布时间】:2014-10-11 16:22:28
【问题描述】:

我有一种情况,我需要在服务中运行一个恒定循环,每次检查某些条件,然后采取适当的措施。从设计的角度来看,使用while (true) 循环非常适合:

while (true)
{
    Process();
}

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

我看到一些参考资料表明这会占用不必要的 CPU 周期,我应该使用 Timer,或者将 Thread.Sleep 添加到循环中。我还看到帖子说使用while (true) 没有任何问题。

在我的开发机器上,它似乎没有负面影响,尽管 CPU 使用率确实上升了。可能是 CPU 使用分散在多个核心上,而部署环境可能只有一个核心。

while (true) 循环是否会对 CPU 性能产生负面影响,如果有,减轻影响的正确方法是什么?

【问题讨论】:

  • while(true) { Task.Run(..) } 肯定会盯住 CPU。请查看 Producer Consumer 模式和 PubSub 模式,了解如何正确执行此操作。

标签: c# while-loop infinite-loop


【解决方案1】:

答案当然是这取决于你在做什么

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。

【讨论】:

    【解决方案2】:

    在协作式多任务系统中,这确实可以固定 CPU(或至少一个内核)。

    但是,大多数现代操作系统都采用抢先式多任务处理,这基本上意味着操作系统控制您的进程获得多少时间。因此,尽管您的循环将使用 100% 的线程(或可能的进程)时间,并剥夺其他人的 一些 CPU 时间,但操作系统将确保准备好运行的其他进程/线程有时间这样做。所以在最坏的情况下,你会放慢速度。

    您要特别注意的一件事是,这样的循环会阻塞运行它的线程,使该线程无法用于其他东西。因此,例如,您不想在 UI 线程上执行此操作。 (有Application.DoEvents(),但你必须经常自己调用它,它的使用表明你正在做一些真正属于它自己线程的事情。)

    【讨论】:

    • 他们不会被完全饿死,但他们会比其他情况下获得更少的 CPU 时间,而这个过程是在浪费时间做任何事情。
    • @Servy:好点(已编辑)。它会占用一些本来可以用于其他进程的时间。但是这个过程只能浪费操作系统允许它拥有的时间,所以它不能独占 CPU,除非有人搞乱优先级和/或操作系统设计不当。
    • 正确,它不会使整个机器完全崩溃,它只会让整个机器变慢。 OP 并不是在问这样做是否会完全破坏他的整个机器,而是在问是否有负面后果。除了“你的电脑不能再做任何事[在这里插入邪恶的笑声]”之外还有负面后果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2014-01-28
    • 2021-04-08
    相关资源
    最近更新 更多