2013-05-22 8 views
11
import Control.Concurrent 
main = do 
    forkIO $ putStrLn "123" 
    forkIO $ putStrLn "456" 

Ich habe den obigen Code geschrieben. Aber als ich es ausführte, bekam ich immer nur 123. 456 wird nicht gedruckt. Ich denke, es ist, weil der Haupt-Thread vor dem anderen Thread beendet wurde, so dass das ganze Programm gerade beendet wurde.Wie kann ich sicherstellen, dass das Haupt-Thread endet, nachdem alle anderen Threads geendet haben?

Wie kann ich das verhindern? Jede API kann sicherstellen, dass der Haupt-Thread beendet ist, nachdem alle Threads geendet haben?

OS: OS X 10.8.3

Compiler: GHC 7.4.2

Antwort

15

Verwenden Sie die async Bibliothek:

import Control.Concurrent.Async 

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

Dies entspricht Daniels Lösung, außer mit zwei leichte Vorteile:

  • Es stellt sicher, dass alle Ausnahmen in den gegabelten Fäden erhalten reraiste im Muttergewinde erhöht, ohne einen Deadlock verursacht
  • Es ist bequemer
+3

3) Es ist leicht für jemanden aus einer anderen Sprache zu verstehen. Async und Wait haben englische Bedeutungen leicht verstanden. Auf der anderen Seite sind "putMvar done()" und "takeMvar done" unverständlich. – 7stud

+4

oder 'gleichzeitig (putStrLn" 123 ") (putStrLn" 456 ")' – JJJ

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) 
+13

mit Ausnahmen von Fragen Vorsicht, though. Wenn eine Ausnahme verhindert, dass ein untergeordneter Thread "putMVar" aufruft, erhalten Sie im Hauptthread "BlockedIndefinitelyOnMVar". Sie können ['forkFinally'] (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html#v:forkFinally) verwenden, um sicherzustellen, dass' putMVar' aufgerufen wird. – hammar

Verwandte Themen