在所有其他线程结束后,如何确保主线程结束?

one*_*uth 11 concurrency haskell

import Control.Concurrent
main = do
    forkIO $ putStrLn "123"
    forkIO $ putStrLn "456"
Run Code Online (Sandbox Code Playgroud)

我已经写了上面的代码.但是当我执行它时,我总是得到它123.456没有打印.我想这是因为主线程在另一个线程之前结束所以整个程序刚刚结束.

我怎么能阻止这个?在所有线程结束后,任何api都可以确保主线程结束?

操作系统:OS X 10.8.3

编译器:ghc 7.4.2

Gab*_*lez 15

使用async图书馆:

import Control.Concurrent.Async

main = do
    a1 <- async $ putStrLn "123"
    a2 <- async $ putStrLn "456"
    mapM_ wait [a1, a2]
Run Code Online (Sandbox Code Playgroud)

这相当于Daniel的解决方案,除了两个小优点:

  • 它确保在父线程中重新引发分叉线程中引发的任何异常,而不会导致死锁
  • 它更方便

  • 或'并发(putStrLn"123")(putStrLn"456")` (4认同)
  • 3)来自其他语言的人很容易理解.'async'和'wait'很容易理解英语的含义.另一方面,">> putMvar done()"和"takeMvar done"是不可理解的. (3认同)

Dan*_*ner 9

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)
Run Code Online (Sandbox Code Playgroud)

  • 但要注意异常问题.如果一个异常阻止子线程调用`putMVar`,你将在主线程中得到一个`BlockedIndefinitelyOnMVar`.您可以使用[`forkFinally`](http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html#v:forkFinally)来确保调用`putMVar`. (14认同)