putStrLn是线程安全的吗?

30

我知道如果多个线程调用putStrLn,没有任何并发控制,那么线程的输出可能会交错。

我的问题是,除了这种交错输出之外,putStrLn是否是线程安全的?

我假设putStrLn是一个缓冲写操作,所以我的问题实际上是,如果两个线程同时调用putStrLn,是否可能破坏输出缓冲区。

并且一般来说,Haskell的(实际上是GHC的)其他“标准I/O”函数的线程安全性如何?特别是对于任何缓冲读取操作,是否可能将相同的字符返回给同时进行相同读取调用的两个不同线程?


我不认为我曾经听说过一个库的标准输出输出不是线程安全的(我想到了通常的C/C++运行时、C#、Java等),所以如果我必须猜测,我会说这里也是可以的。 +1 好问题。 - user541686
在Linux上,putStrLn和其他函数是通过writeselect组合实现的,用于固定长度的块(当使用行缓冲或块缓冲时),因此问题是write是否线程安全。 POSIX要求write具有线程安全性(1003.1-2001:2.9.1&2.9.7),通常情况下它是线程安全的。 - JJJ
MVar 锁是使用 futex 实现的(当使用 threaded 运行时)。因此,@shachaf 的答案是正确的。 - JJJ
1个回答

28

是的,在你询问的意义上,它是线程安全的。一个Handle由一个MVar保护,该保护不允许缓冲区变得损坏。但是,正如你指出的那样,交错是另一回事。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接