2010-06-05 11 views
23

Ho due thread in haskell che eseguono l'IO. (Stampa solo). Qualcosa di simile a quanto segue:Posso garantire che Haskell esegua l'I/O atomico?

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

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

Attualmente sto ottenendo risultati come il seguente:

OnTwoe 
OTnweo 

Come posso garantire che ogni thread completa il suo IO atomico?

risposta

23

Questa è una buona domanda. Utilizzare una variabile di sincronizzazione per garantire l'accesso atomico alla risorsa. Un modo semplice è un MVAR:

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

Ora, fare IO senza interleaving, ogni filo impiega la serratura:

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

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

Un disegno alternativo è quello di avere un thread di lavoro dedicato che fa tutto il putStrLns e invii messaggi per stampare su un Chan.

+4

Come esercizio: provare a scrivere questo utilizzando la memoria transazionale per ordinare l'accesso alla risorsa. –

+2

Lo farò uno scatto! anche io ho cambiato: withMVar lock $ (\ _ -> putStrLn "bar") – Toymakerii

+1

Non ho usato questo disegno ma il design alternativo che menzioni alla fine ha funzionato abbastanza bene per me in un paio di progetti. –

Problemi correlati