2010-06-05 12 views
23

Ich habe zwei Threads in Haskell, die IO durchführen. (Sie drucken nur). So etwas wie die folgenden:Kann ich sicherstellen, dass Haskell atomare IO ausführt?

thread1 :: IO() 
thread1 = putStrLn "One" 

thread2 :: IO() 
thread2 = putStrLn "Two" 

Ich bin derzeit immer Ergebnisse wie folgt aus:

OnTwoe 
OTnweo 

Wie kann ich sicherstellen, dass jeder Thread atomar seine IO abgeschlossen?

Antwort

23

Das ist eine gute Frage. Verwenden Sie eine Synchronisationsvariable, um den atomaren Zugriff auf die Ressource sicherzustellen. Ein einfacher Weg ist mit einem MVar:

main = do 
    lock <- newMVar() 
    forkIO $ ... lock 
    forkIO $ ... lock 

, nun IO zu tun, ohne Verschachtelung nimmt jeder Thread die Sperre:

thread1 lock = do 
     withMVar lock $ \_ -> putStrLn "foo" 

thread2 lock = do 
     withMVar lock $ \_ -> putStrLn "bar" 

Ein alternatives Design ist einen dedizierten Worker-Thread zu haben, die alle funktionieren die putStrLns, und Sie senden Nachrichten zum Ausdrucken über einen Chan.

+4

Als Übung: Versuchen Sie, dies mit Transaktionsspeicher zu schreiben, um den Zugriff auf die Ressource zu bestellen. –

+2

Ich werde das geben! habe ich auch geändert: mit MVar lock $ (\ _ -> putStrLn "bar") – Toymakerii

+1

Ich habe diesen Entwurf nicht verwendet, aber das alternative Design, das Sie am Ende erwähnen, hat ziemlich gut für mich in ein paar Projekten gearbeitet. –

Verwandte Themen