[Haskell-cafe] scheduling an alarm
Neil Brown
nccb2 at kent.ac.uk
Thu Jan 28 10:21:27 EST 2010
Brian Denheyer wrote:
> On Tue, 26 Jan 2010 22:41:44 -0800
> Thomas DuBuisson <thomas.dubuisson at gmail.com> wrote:
>
>>>>> doEvent f usDelay = forkIO $
>>>>> threadDelay usDelay
>>>>> doEvent f usDelay
>>>>> f
>>>>>
>>> Are you sure that's right ? It seems to be a memory-gobbling
>>> infinite loop...
>>>
>>
>
> Why would I think that ?
> I think that because the following code:
>
> import Control.Concurrent
>
> f = putStrLn "foo"
>
> doEvent f usDelay = do forkIO $ threadDelay usDelay
> doEvent f usDelay
> f
>
> _really_ _does_ start to consume all of the memory on my system, that's
> why. I don't know why, but that's what it does on my system. It's not
> obvious to me that it should do that. So maybe ghci is not doing TCO.
>
The code you have presented at the bottom is an infinite loop that I
would expect to consume all the memory on your system. That code spins
at 100% busy, forking off threadDelay calls without ever stopping, and
will never perform "f". Ouch -- infinite loop, and likely hugely
memory-consuming (in fact, I'm not sure how the last poster didn't find
that it consumed a lot of memory...). However, that code is slightly
different to the original (that I have left in up the top) which had a
crucial "do" missing (although you can infer it from the indentation).
The original code should be:
doEvent f usDelay = forkIO $ do threadDelay usDelay
doEvent f usDelay
f
That is, the latter two lines should be inside the forkIO block, not
after it. This code will wait for the given delay, then fork a new
thread, then perform f. As long as f takes less time to complete than
usDelay, this code should not eat memory and is quite reasonable.
I hope that clears up the confusion.
Neil.
More information about the Haskell-Cafe
mailing list