RE: NON-daemonic forking
[posting to the right list... ] I guess not. How can you define a non-daemonic forkIO in terms of a daemonic one? Both suggestions so far involve adding something extra to the end of the main thread to wait on MVars. And as a matter of fact, neither of these solutions address the problem of an exception in the main thread itself. The only way I can see of implementing non-daemonic fork would be to insist that the user always write main functions with a containing try-finally clause (or whatever it's called) which does the business of waiting for any unfinished non-daemonic threads. This is what I'd do. You do need the top-level enclosing exception handler, but its not at all painful and any program that pretends to be robust will need one anyway: (this code is completely untested, BTW) import Exception children :: MVar [MVar ()] children = unsafePerformIO (newMVar []) waitForChildren :: IO () waitForChildren = do (mvar:mvars) - takeMVar children putMVar children mvars takeMVar mvar waitForChildren forkNonDaemonic :: IO () - IO () forkNonDaemonic io = do mvar - newEmptyMVar forkIO (p `finally` putMVar mvar ()) childs - takeMVar children putMVar children (mvar:childs) later = flip finally main = later waitForChildren $ ... The trick of having a top-level global mutable variable or MVar is turning up in a disturbingly large proportion of the code I tend to write these days :) Cheers, Simon
Re: NON-daemonic forking
Michael Weber [EMAIL PROTECTED] wrote [snip] forkChild :: IO () - IO (MVar ()) forkChild p = do mvar - newEmptyMVar forkIO (p putMVar mvar ()) return mvar This does not of course synthesise a non-daemonic forkIO from a daemonic one, because it requires the parent thread to wait for the MVar. I suppose that a possible alternative to having separate daemonic and non-daemonic forking would be to have an atexit-type function: atThreadExit :: IO () - IO() which forkChild could use to wait for the mvar. But I'm not sure I like this, unless there are other likely uses for atThreadExit.
Re: NON-daemonic forking
On Fri, Aug 20, 1999 at 15:34:51 +0200, George Russell wrote: Einar Karlson, my predecessor, asked for daemonic forking as for Java. In Java you have ordinary threads and daemonic threads; the process ends when only daemonic threads are still running. The GHC team seem to have gone ahead and made all forked thread daemonic! So can we have ordinary threads back please? Still, daemonic threads are nice, and I wonder whether we should really have two fork functions, since I can't right now think of a way of synthesising one from the other. How about this one :-) \begin{code} import Concurrent( forkIO, MVar, newEmptyMVar, putMVar, readMVar, yield ) main :: IO () main = do t1 - forkChild (forever $ putChar 'a') t2 - forkChild (forever $ putChar 'b') waitForChilds [t1, t2] where forever :: IO a - IO a forever p = p yield forever p \end{code} \begin{code} forkChild :: IO () - IO (MVar ()) forkChild p = do mvar - newEmptyMVar forkIO (p putMVar mvar ()) return mvar waitForChilds :: [MVar ()] - IO () waitForChilds [] = return () waitForChilds (p:ps) = readMVar p waitForChilds ps \end{code} Cheers, Michael -- W*ndoze NT is faster... CRASHING!