我可以确保 Haskell 执行原子 IO 吗?
Posted
技术标签:
【中文标题】我可以确保 Haskell 执行原子 IO 吗?【英文标题】:Can I ensure that Haskell performs atomic IO? 【发布时间】:2011-02-28 05:55:26 【问题描述】:我在 haskell 中有两个线程来执行 IO。 (他们只打印)。类似于以下内容:
thread1 :: IO ()
thread1 = putStrLn "One"
thread2 :: IO ()
thread2 = putStrLn "Two"
我目前得到如下结果:
OnTwoe
OTnweo
如何确保每个线程自动完成其 IO?
【问题讨论】:
【参考方案1】:使用同步变量来确保对资源的原子访问。一种简单的方法是使用 MVar:
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 打印出来。
【讨论】:
作为一个练习:尝试使用事务性内存来编写此命令以访问资源。 我会试一试的!我也改变了:withMVar lock $ (_ -> putStrLn "bar") 我没有使用过这种设计,但你最后提到的替代设计在几个项目中对我来说效果很好。 如果monad上下文不在IO中怎么办?我使用的是monad-parallel
包,它能够派生非 IO 的单子。我不能将 mVars
用于非 IO 单子。
@Toymakerii 是正确的。 withMVar
的第二个参数应该是一个函数,而不仅仅是putStrLn "..."
。以上是关于我可以确保 Haskell 执行原子 IO 吗?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Haskell 没有符号(a la ruby)/原子(a la erlang)?