我可以确保 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 IO 执行顺序

Haskell 函数可以序列化吗?

为啥 Haskell 没有符号(a la ruby​​)/原子(a la erlang)?

Haskell语言学习笔记(19)File IO

Haskell openGL 和 GLUT 在 Mac OS X 上冻结?我可以在 GLUT 上使用 GLFW 吗?

Linux设备驱动程序 之 原子操作