Haskell循环构建100%CPU

时间:2012-08-21 22:14:54

标签: macos haskell ghc osx-leopard

我有一个我无法弄清楚的错误。使用Haskell Platform 2010,GHC 6.12

,系统为10.5(32位)

请考虑以下事项:

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

main = do
    loop

编译时,

ghc --make test.hs

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

Concurrent的“收益率”似乎没有做任何有趣的事情。

4 个答案:

答案 0 :(得分:9)

同样的原因,任何语言的紧密循环都会占用整个CPU。你并没有告诉它循环任何慢于“尽可能快”。查看Control.Concurrent的{​​{1}}。

答案 1 :(得分:8)

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

答案 2 :(得分:4)

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

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

或者没有递归:

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

所有这些都可以用任何语言告诉CPU永远执行没有有用结果的指令。没有特别告诉程序执行其他而不是继续执行这些指令(例如在循环之间暂停一段时间),除了使用100%CPU之外,它怎么能做什么?

Control.Concurrent.yield允许程序中的任何其他线程在执行时“转弯”。如果没有其他线程,则它不会执行任何操作。如果 all 你的其他线程正在执行这样的循环,那么它仍然会使用100%的CPU。如果你有其他线程有时IO绑定而不是CPU绑定,我不确定,但我有理由相信Haskell的运行时系统切换回CPU要做的事情(如果可能),每当线程等待IO ,如果你有这个循环运行和yield,你可能会看到接近100%的CPU使用率,即使你有很多其他线程不能自己使用100%的CPU。

如果其他不相关的程序也在运行,那么几乎所有现代桌面硬件和操作系统都会尝试在它们之间共享CPU资源,无论您是否使用yield。通常,这意味着只要其他程序没有为CPU运行,你的循环程序就会运行, plus 它也会窃取一些可能用于执行其他程序的CPU时间程式。这意味着在执行此循环程序时,无论运行的是什么,通常都会看到接近100%的CPU使用率,并且使用yield对于其他程序可用的CPU时间没有特别的影响

Control.Concurrent.threadDelay使线程休眠(至少)给定的时间。如果这使得CPU无需执行任何操作,那么然后您将看到系统在低于100%的CPU运行。

答案 3 :(得分:1)

在您的循环中插入delay,以便将处理器时间提供给另一个进程。