What's the best way to exit a Haskell program? What's the best way to exit a Haskell program? multithreading multithreading

What's the best way to exit a Haskell program?


You can use Control.Concurrent.MVar to achieve this. An MVar is essentially a flag which is either ''empty'' or "full". A thread can try to read an MVar and if it is empty it blocks the thread. Wherever you have a thread which performs file IO, create an MVar for it, and pass it that MVar as an argument. Put all the MVars you create into a list:

main = do  let mvars = sequence (replicate num_of_child_threads newEmptyMVar)  returnVals <- sequence (zipWith (\m f -> f m)                                   mvars                                   (list_of_child_threads :: [MVar -> IO a])) 

Once a child thread has finished all file operations that you are worried about, write to the MVar. Instead of writing killThread you can do

mapM_ takeMVar mvars >> killThread 

and where-ever your thread would exit otherwise, just take all the MVars.

See the documentation on GHC concurrency for more details.


From my testing, I have discovered a few things:

  1. exitFailure and friends only work in thread 0. (The documentation actually says so, if you go to the trouble of reading it. These functions just throw exceptions, which are silently ignored in other threads.)

  2. If an exception kills your thread, or your whole program, any open handles are not flushed. This is excruciatingly annoying when you're desperately trying to figure out exactly where your program crashed!

So it appears it if you want your stuff flushed before the program exits, then you have to implement this. Just letting thread 0 die doesn't flush stuff, doesn't throw any exception, just silently terminates all threads without running exception handlers.