-1

我有一个我无法真正弄清楚的错误。系统为 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 的“产量”似乎没有做任何有趣的事情。

4

4 回答 4

9

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

于 2012-08-21T22:33:23.373 回答
8

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

于 2012-08-21T22:41:00.987 回答
4

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

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

或者没有递归:

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

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

Control.Concurrent.yield allows any other thread in your program to "get a turn" at execution. If there are no other threads then it doesn't do anything. If all your other threads are executing such a loop, then it'll still use 100% CPU. If you have other threads that are sometimes IO bound rather than CPU bound, I do not know for certain, but I'm reasonably sure Haskell's runtime system switch back to something for the CPU to do (if possible) whenever threads are waiting for IO, so you'd probably see close to 100% CPU usage if you had this loop running and yielding, even if you have loads of other threads that won't use 100% CPU on their own.

If other unrelated programs are also running, then almost all modern desktop hardware and operating systems will try to share the CPU resources between them, regardless of whether you're using yield or not. Generally, this means that any time the other programs don't have work for the CPU your loop program will be run, plus it will also steal some of the CPU time that could have been used to execute other programs. This means that while this loop program is executing you would usually see close to 100% CPU usage regardless of what else is running, and using yield won't particularly make a difference to how much CPU time is available to other programs.

Control.Concurrent.threadDelay puts the thread to sleep for (at least) a given amount of time. If that leaves the CPU with nothing to execute, then you'll see your system running at less than 100% CPU.

于 2012-08-22T01:17:57.743 回答
1

在循环中插入延迟,以便将处理器时间分配给另一个进程。

于 2012-08-21T22:33:22.327 回答