Как я могу убедиться, что основная нить заканчивается после окончания всех остальных концов?
import Control.Concurrent
main = do
forkIO $ putStrLn "123"
forkIO $ putStrLn "456"
Я написал код выше. Но когда я его выполнил, я всегда получал только 123
. 456
не печатается. Я думаю, это потому, что основной поток закончился до другого потока, так что вся программа только что закончилась.
Как я могу это предотвратить? Любой api может удостовериться, что основной поток закончился после того, как закончились все потоки?
ОС: OS X 10.8.3
компилятор: ghc 7.4.2
Ответы
Ответ 1
Используйте библиотеку async
:
import Control.Concurrent.Async
main = do
a1 <- async $ putStrLn "123"
a2 <- async $ putStrLn "456"
mapM_ wait [a1, a2]
Это эквивалентно решению Дэниела, за исключением двух незначительных преимуществ:
- Он гарантирует, что любые исключения, возникающие в разветвленных потоках, будут повторно подняты в родительском потоке без возникновения тупика.
- Это более удобно
Ответ 2
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)