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
To execute threads one after another it needs to be synchronized. wait notify notifyAll is useful. This is the famous interview question for the beginners, Write a program that creates 3 threads and prints alternate values in sequence.
We can use join() methodto ensure all threads that started from main must end in order in which they started and also main should end in last.In other words waits for this thread to die. Calling join() method internally calls join(0).
thread. join() waits for the thread to finish before it continues. So the sub-thread will wait for each of the threads that it spawned to finish and then it will finish. The main thread will wait for the sub-thread to finish and will then finish last.
Barriers. Barriers are a synchronization mechanism that can be used to coordinate multiple threads working in parallel. A barrier allows each thread to wait until all cooperating threads have reached the same point, and then continue executing from there.
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:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With