2010-06-05 20 views
23

Tengo dos hilos en haskell que realizan IO. (Solo imprimen). Algo parecido a lo siguiente:¿Puedo asegurarme de que Haskell realice IO atómico?

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

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

actualmente estoy consiguiendo resultados como el siguiente:

OnTwoe 
OTnweo 

Cómo puedo estar seguro de que cada hilo completa su IO atómicamente?

Respuesta

23

Esta es una buena pregunta. Use una variable de sincronización para garantizar el acceso atómico al recurso. Una forma sencilla es con un MVar:

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

Ahora, para hacer IO sin entrelazado, cada hilo toma la cerradura:

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

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

Un diseño alternativo es tener un subproceso de trabajo dedicado que hace todo el putStrLns, y usted envía mensajes para imprimir sobre un Chan.

+4

Como ejercicio: intente escribir esto usando la memoria transaccional para ordenar el acceso al recurso. –

+2

¡Daré una oportunidad! también cambié: conMVar lock $ (\ _ -> putStrLn "bar") – Toymakerii

+1

No he usado este diseño, pero el diseño alternativo que menciona al final me ha funcionado bastante bien en un par de proyectos. –

Cuestiones relacionadas