【问题标题】:Haskell concurrency IO behaviorHaskell 并发 IO 行为
【发布时间】:2010-08-15 07:17:48
【问题描述】:

我正在尝试更深入地了解 Haskell 中的并发性。我有以下代码:

import Control.Concurrent
    main :: IO ()

    main = do 
    arr <- return $ [1..9]
    t <- newMVar 1
    forkIO (takeMVar t >> (print.show) arr >> putMVar t 1)
    forkIO (takeMVar t >> (print.show) arr >> putMVar t 1)
    forkIO (takeMVar t >> (print.show) arr >> putMVar t 1)
    forkIO (takeMVar t >> (print.show) arr >> putMVar t 1)
    forkIO (takeMVar t >> (print.show) arr >> putMVar t 1)
    return ()

有时我看到打印操作重叠,我得到以下结果(查看第二个调用):

*Main Control.Concurrent> :l test.hs 
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main Control.Concurrent> main
"[1,2,3,4,5,6,7,8,9]"
"[1,2,3,4,5,6,7,8,9]"
"[1,2,3,4,5,6,7,8,9]"
"[1,2,3,4,5,6,7,8,9]"
"[1,2,3,4,5,6,7,8,9]"
*Main Control.Concurrent> main
"[1,2,3,4,5,6,7,8,9]"
"[1,2,3,4,5,6,7,8,9]"
"[1,2,3,4,5,6,7,8,9]"
["[1,2,3,4,5,6,7,8,9]"
?"[1,2,3,4,5,6,7,8,9]"
1h*Main Control.Concurrent> 

我不明白为什么会这样。将 MVar 用于[1..9] 也很糟糕。

【问题讨论】:

  • 问题是主线程比子线程更早完成。如果我们将等待所有子线程没有重叠出现。
  • 另外,print = putStrLn.showprint.show调用show两次,有点多余。

标签: haskell concurrency io


【解决方案1】:

有时我看到打印操作重叠

输出有时会重叠,因为标准输出上存在锁定。每个线程调用“print”,它试图写出一个字符,为每个字符获取锁。由于 Haskell 的抢占式并发,您将看到线程打印的随机交错。

如果这是不受欢迎的行为,则改为让每个线程将它希望打印的字符串发送到打印机线程,然后打印机线程将按顺序逐行输出。

【讨论】:

  • 据我了解,您使用 haskell stdout 在单独的线程中打印出每个字符?我说的对吗?
猜你喜欢
  • 2019-03-28
  • 2016-03-04
  • 2013-03-25
  • 2020-02-03
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多