2010-06-05 38 views
23

我有两个线程在执行IO的haskell中。 (他们只打印)。像下面这样:我可以确保Haskell执行原子IO吗?

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

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

我目前得到的结果如下所示:

OnTwoe 
OTnweo 

我怎样才能确保每个线程原子地完成其IO?

回答

23

这是一个很好的问题。使用同步变量来确保对资源的原子访问。一个简单的方法是使用无功:

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

现在,做IO无交错,每个线程需要的锁:

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

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

另一种设计是有一个专门的工作线程执行所有putStrLns,并发送消息通过Chan打印出来。

+4

作为练习:尝试使用事务内存编写此命令来订购对资源的访问。 – 2010-06-05 21:08:57

+2

我会给你一枪! 我也改变了: withMVar lock $(\ _ - > putStrLn“bar”) – Toymakerii 2010-06-05 22:26:02

+1

我还没有使用过这个设计,但是最后提到的替代设计在我的几个项目中工作得很好。 – 2015-06-08 09:44:55

相关问题