开发者

Why putStrLn end of line is out of thread lock?

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 someth开发者_Go百科ing 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


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜