【问题标题】:Can I ensure that Haskell performs atomic IO?我可以确保 Haskell 执行原子 IO 吗?
【发布时间】:2011-02-28 05:55:26
【问题描述】:

我在 haskell 中有两个线程来执行 IO。 (他们只打印)。类似于以下内容:

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

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

我目前得到如下结果:

OnTwoe
OTnweo

如何确保每个线程自动完成其 IO?

【问题讨论】:

    标签: multithreading haskell io concurrency


    【解决方案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 "..."
    猜你喜欢
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2012-06-09
    • 2018-08-14
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2011-05-12
    相关资源
    最近更新 更多