-1

よくわからないバグがあります。システムは、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 の "yield" は、何も面白いことをしていないようです。

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プログラム内の他のスレッドが実行時に「ターンを取得」できるようにします。他にスレッドがない場合は、何もしません。他のすべてのスレッドがそのようなループを実行している場合でも、100%のCPUを使用します。CPUバウンドではなくIOバウンドになることがある他のスレッドがある場合、確かなことはわかりませんが、スレッドがIOを待機しているときはいつでも、HaskellのランタイムシステムがCPUが実行できるものに戻ると合理的に確信しています。したがって、このループを実行して実行しyieldている場合は、100%CPUを単独で使用しない他のスレッドがたくさんある場合でも、おそらく100%近くのCPU使用率が表示されます。

他の無関係なプログラムも実行されている場合、ほとんどすべての最新のデスクトップハードウェアとオペレーティングシステムは、使用しているかどうかに関係なく、それらの間でCPUリソースを共有しようとしますyield。一般に、これは、他のプログラムがCPUに対して機能しない場合はいつでも、ループプログラムが実行されることを意味します。さらに、他のプログラムの実行に使用された可能性のあるCPU時間の一部も盗みます。つまり、このループプログラムの実行中は、他に何が実行されているかに関係なく、通常100%近くのCPU使用率が表示yieldされます。使用しても、他のプログラムで使用できるCPU時間に特に違いはありません。

Control.Concurrent.threadDelayスレッドを(少なくとも)指定された時間スリープ状態にします。それでもCPUに実行するものがない場合は、システムが100%未満のCPUで実行されていることがわかります。

于 2012-08-22T01:17:57.743 に答える
1

ループに遅延を挿入して、プロセッサ時間が別のプロセスに与えられるようにします。

于 2012-08-21T22:33:22.327 に答える