[reactive] problem with unamb -- doesn't kill enough threads

Simon Marlow marlowsd at gmail.com
Fri Dec 19 04:48:33 EST 2008


Sounds like you should use an exception handler so that when the parent 
dies it also kills its children.  Be very careful with race conditions ;-)

For a good example of how to do this sort of thing, see

http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-Timeout.html

the docs are sadly missing the source links at the moment, I'm not sure 
why, but you can find the source in

http://darcs.haskell.org/packages/base/System/Timeout.hs

Cheers,
	Simon

Conal Elliott wrote:
> (I'm broadening the discussion to include haskell-cafe.)
> 
> Andy -- What do you mean by "handling all thread forking locally"?
> 
>   - Conal
> 
> On Thu, Dec 18, 2008 at 1:57 PM, Andy Gill <andygill at ku.edu 
> <mailto:andygill at ku.edu>> wrote:
> 
>     Conal, et. al,
> 
>     I was looking for exactly this about 6~9 months ago. I got the
>     suggestion to pose it as a challenge
>     to the community by Duncan Coutts. What you need is thread groups,
>      where for a ThreadId, you can send a signal
>     to all its children, even missing generations if needed. 
> 
>     I know of no way to fix this at the Haskell level without handling
>     all thread forking locally. 
> 
>     Perhaps a ICFP paper about the pending implementation :-) but I'm
>     not sure about the research content here.
> 
>     Again, there is something deep about values with lifetimes. 
> 
>     Andy Gill
> 
> 
>     On Dec 18, 2008, at 3:43 PM, Conal Elliott wrote:
> 
>>     I realized in the shower this morning that there's a serious flaw
>>     in my unamb implementation as described in
>>     http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice. 
>>     I'm looking for ideas for fixing the flaw.  Here's the code for
>>     racing computations:
>>
>>         race :: IO a -> IO a -> IO a
>>         a `race` b = do v  <- newEmptyMVar
>>                         ta <- forkPut a v
>>                         tb <- forkPut b v
>>                         x  <- takeMVar  v
>>                         killThread ta
>>                         killThread tb
>>                         return x
>>
>>         forkPut :: IO a -> MVar a -> IO ThreadId
>>         forkPut act v = forkIO ((act >>= putMVar v) `catch` uhandler
>>     `catch` bhandler)
>>          where
>>            uhandler (ErrorCall "Prelude.undefined") = return ()
>>            uhandler err                             = throw err
>>            bhandler BlockedOnDeadMVar               = return ()
>>
>>     The problem is that each of the threads ta and tb may have spawned
>>     other threads, directly or indirectly.  When I kill them, they
>>     don't get a chance to kill their sub-threads.
>>
>>     Perhaps I want some form of garbage collection of threads, perhaps
>>     akin to Henry Baker's paper "The Incremental Garbage Collection of
>>     Processes".  As with memory GC, dropping one consumer would
>>     sometimes result is cascading de-allocations.  That cascade is
>>     missing from my implementation.
>>
>>     Or maybe there's a simple and dependable manual solution,
>>     enhancing the method above.
>>
>>     Any ideas?
>>
>>        - Conal
>>
>>
>>     _______________________________________________
>>     Reactive mailing list
>>     Reactive at haskell.org <mailto:Reactive at haskell.org>
>>     http://www.haskell.org/mailman/listinfo/reactive
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Reactive mailing list