为什么 putStrLn 行尾没有线程锁?
当我在 Haskell 中的多个线程中使用 putStrLn txt 时,可以将文本插入到行尾,但是如果我使用 putStr $ txt ++ "\n" 总是有效。
是吗?我做错了什么?
示例 1:
thread 1: putStrLn "txt 1"
thread 2: putStrLn "txt 2"
thread 3: putStrLn "txt 3"
thread 4: putStrLn "txt 4"
thread 5: putStrLn "txt 5"
输出示例:
txt 1txt 3
txt 2txt 5txt 4
示例 2:
thread 1: putStr $ "txt 1" ++ "\n"
thread 2: putStr $ "txt 2" ++ "\n"
thread 3: putStr $ "txt 3" ++ "\n"
thread 4: putStr $ "txt 4" ++ "\n"
thread 5: putStr $ "txt 5" ++ "\n"
始终为线程输出一行:
txt 1
txt 3
txt 2
txt 5
txt 4
谢谢
更新: 我正在使用 ghc 6.12.3
和 base-4.2.0.2
When I use putStrLn txt
from several threads in Haskell, it's possible to get the text intercalated with the end of lines, but if I use putStr $ txt ++ "\n"
always works.
is it right? What am I doing something wrong?
Example 1:
thread 1: putStrLn "txt 1"
thread 2: putStrLn "txt 2"
thread 3: putStrLn "txt 3"
thread 4: putStrLn "txt 4"
thread 5: putStrLn "txt 5"
Example of output:
txt 1txt 3
txt 2txt 5txt 4
Example 2:
thread 1: putStr $ "txt 1" ++ "\n"
thread 2: putStr $ "txt 2" ++ "\n"
thread 3: putStr $ "txt 3" ++ "\n"
thread 4: putStr $ "txt 4" ++ "\n"
thread 5: putStr $ "txt 5" ++ "\n"
Always output one line for thread:
txt 1
txt 3
txt 2
txt 5
txt 4
Thanks
Update:
I'm using ghc 6.12.3
and base-4.2.0.2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我所知,Haskell 不为 putStr、putStrLn 等提供任何线程安全保证,因此也允许逐个字符交错,即使像您一样预先进行串联。
请参阅我可以确保 Haskell 执行原子 IO 吗?如何正确同步 I/O 的示例。
As far as I can tell, Haskell doesn't provide any thread safety guarantees on
putStr
,putStrLn
and friends, so it would also be allowed to interleave character-by-character, even when doing the concatenation up front like you do.See Can I ensure that Haskell performs atomic IO? for an example of how to synchronize your I/O properly.
根据基础 4.3.0.0 的定义(
putStrLn s = do putStr s; putChar '\n'
- 感谢 hammar),我假设putStr
锁定stdout
句柄,因此能够输出没有插入的字符串。这可以解释为什么使用putStrLn
时输出会插入:锁在putStr
之后释放,另一个线程在putChar
之前获取锁。不过我只是猜测。无论如何,将 GHC 及其基础库更新到 4.3.1.0 应该可以解决问题。
With the definition from base 4.3.0.0 (
putStrLn s = do putStr s; putChar '\n'
- thanks hammar) I would assume thatputStr
locks thestdout
handle and is therefore able to output the string without intercalation. That would explain why the output intercalates when usingputStrLn
: the lock is released afterputStr
and another thread acquires the lock beforeputChar
. I'm only speculating, though.In any case, updating GHC and with it the base library to 4.3.1.0 should fix the problem.