为什么 putStrLn 行尾没有线程锁?

发布于 2024-11-19 06:35:42 字数 774 浏览 5 评论 0原文

当我在 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.3base-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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

虫児飞 2024-11-26 06:35:42

据我所知,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.

像你 2024-11-26 06:35:42

根据基础 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 that putStr locks the stdout handle and is therefore able to output the string without intercalation. That would explain why the output intercalates when using putStrLn: the lock is released after putStr and another thread acquires the lock before putChar. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文