【问题标题】:Haskell Looping Construct 100% CPUHaskell 循环构造 100% CPU
【发布时间】:2012-08-21 22:14:54
【问题描述】:

我有一个我无法弄清楚的错误。系统为 10.5(32 位),采用 Haskell 平台 2010,GHC 6.12

考虑以下几点:

loop :: IO ()
loop = do
    return ()
    loop

main = do
    loop

编译时,

ghc --make test.hs

此代码最终会占用 100% 的 CPU 时间。这是为什么? 你如何在 Haskell 中编写一个这样循环的程序,同时又对笔记本电脑的电池很好?

Concurrent 的“yield”似乎没有做任何有趣的事情。

【问题讨论】:

  • 仅供参考,'yield' 没有做任何有趣的事情的原因是'yield' 告诉 Haskell 运行时让步给另一个 Haskell 线程。由于没有其他 Haskell 线程,相同的循环将继续,不会有太多的停顿。
  • 你到底为什么想要这个?也许如果你解释你想要达到什么(除了浪费处理器周期),有人可以帮助你更好的方法来做到这一点。

标签: macos haskell ghc osx-leopard


【解决方案1】:

同样的原因,任何语言的紧密循环都会占用整个 CPU。你没有告诉它循环比“尽可能快”慢。看Control.ConcurrentthreadDelay

【讨论】:

    【解决方案2】:

    没有中断的无限循环将导致任何计算机上任何语言的 100% CPU 使用率
    如果您必须执行这样的循环,请使用delaysleep 或降低线程的优先级(如果它占用了太多循环)。

    【讨论】:

      【解决方案3】:

      类似的命令式(类似 Python 的语法)循环是:

      def loop():
          x = ()
          loop()
      

      或者没有递归:

      def loop():
         while True:
             x = ()
      

      所有这些在任何语言中都会做的就是告诉 CPU 继续执行没有有用结果的指令,永远。除了继续执行这些指令(例如在循环之间暂停一段时间)之外,没有明确告诉程序执行其他操作其他,除了使用 100% 的 CPU 之外,它还能做什么?

      Control.Concurrent.yield 允许您的程序中的任何其他线程 在执行时“获得转机”。如果没有其他线程,那么它什么也不做。如果所有你的其他线程正在执行这样一个循环,那么它仍然会使用 100% 的 CPU。如果您有其他线程有时受 IO 限制而不是 CPU 限制,我不确定,但我有理由确定 Haskell 的运行时系统切换回 CPU 执行的操作(如果可能),只要线程等待 IO ,因此如果您运行此循环并yielding,您可能会看到接近 100% 的 CPU 使用率,即使您有大量其他线程本身不会使用 100% 的 CPU。

      如果其他不相关的程序也在运行,那么几乎所有现代桌面硬件和操作系统都会尝试在它们之间共享 CPU 资源,无论您是否使用yield。通常,这意味着任何时候其他程序没有为 CPU 工作,您的循环程序就会运行,加上它还会窃取一些本可以用于执行其他程序的 CPU 时间程式。这意味着当这个循环程序正在执行时,无论其他程序正在运行,您通常会看到接近 100% 的 CPU 使用率,并且使用 yield 不会特别影响其他程序可以使用多少 CPU 时间。

      Control.Concurrent.threadDelay 让线程休眠(至少)一段给定的时间。如果这让 CPU 无事可做,那么你会看到你的系统以低于 100% 的 CPU 运行。

      【讨论】:

        【解决方案4】:

        在循环中插入delay,以便将处理器时间分配给其他进程。

        【讨论】:

          猜你喜欢
          • 2012-09-25
          • 2010-11-16
          • 1970-01-01
          • 2012-04-25
          • 2013-05-14
          • 2015-01-21
          • 2020-11-24
          • 2018-12-06
          • 1970-01-01
          相关资源
          最近更新 更多