onemouth
onemouth

Reputation: 2277

How can I make sure main thread ends after all other threads ends?

import Control.Concurrent
main = do
    forkIO $ putStrLn "123"
    forkIO $ putStrLn "456"

I have written the code above. But when I executed it, I always got 123 only. 456 is not printed. I guess it is because main thread ended before the other thread so the whole program just ended.

How can I prevent this? Any api can make sure main thread ended after all threads ended?

OS: OS X 10.8.3

compiler: ghc 7.4.2

Upvotes: 11

Views: 927

Answers (2)

Gabriella Gonzalez
Gabriella Gonzalez

Reputation: 35089

Use the async library:

import Control.Concurrent.Async

main = do
    a1 <- async $ putStrLn "123"
    a2 <- async $ putStrLn "456"
    mapM_ wait [a1, a2]

This is equivalent to Daniel's solution, except with two slight advantages:

  • It ensures that any exceptions raised in the forked threads get re-raised in the parent thread without causing a deadlock
  • It's more convenient

Upvotes: 16

Daniel Wagner
Daniel Wagner

Reputation: 152682

import Control.Concurrent
main = do
    done <- newEmptyMVar
    forkIO $ putStrLn "123" >> putMVar done ()
    forkIO $ putStrLn "456" >> putMVar done ()
    takeMVar done
    takeMVar done
    -- OR: replicateM_ 2 (takeMVar done)

Upvotes: 9

Related Questions