Haskell 并发 IO 行为

标签 haskell concurrency io

我试图更深入地了解 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] 效果也不好。

最佳答案

Sometimes i see that the print operations overlaps

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

如果这是不良行为,则让每个线程将其希望打印的字符串发送到打印机线程,然后打印机线程将依次执行逐行输出。

关于Haskell 并发 IO 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3486549/

相关文章:

c# - 我使用 IO 的所有操作都应该是异步的吗?

python - 读/写文本文件

固定长度的 Haskell powerset 子列表

haskell - Haskell 中命名字段的令人惊讶的类型推断

java - 套接字上并发读写的线程安全

java - 什么时候调用 java 的 thread.run() 而不是 thread.start()?

file - 如果在读取之前它不存在,则haskell 将其写入文件

haskell - 无法理解 State Monad 如何在此代码中获取它的状态

haskell - haskell中解压功能的实现

使用 ConcurrentHashMap 进行 Kotlin 并发,同时在不使用锁的情况下检索和删除