我知道如果多个线程调用putStrLn
,没有任何并发控制,那么线程的输出可能会交错。
我的问题是,除了这种交错输出之外,putStrLn
是否是线程安全的?
我假设putStrLn
是一个缓冲写操作,所以我的问题实际上是,如果两个线程同时调用putStrLn
,是否可能破坏输出缓冲区。
并且一般来说,Haskell的(实际上是GHC的)其他“标准I/O”函数的线程安全性如何?特别是对于任何缓冲读取操作,是否可能将相同的字符返回给同时进行相同读取调用的两个不同线程?
我知道如果多个线程调用putStrLn
,没有任何并发控制,那么线程的输出可能会交错。
我的问题是,除了这种交错输出之外,putStrLn
是否是线程安全的?
我假设putStrLn
是一个缓冲写操作,所以我的问题实际上是,如果两个线程同时调用putStrLn
,是否可能破坏输出缓冲区。
并且一般来说,Haskell的(实际上是GHC的)其他“标准I/O”函数的线程安全性如何?特别是对于任何缓冲读取操作,是否可能将相同的字符返回给同时进行相同读取调用的两个不同线程?
putStrLn
和其他函数是通过write
和select
组合实现的,用于固定长度的块(当使用行缓冲或块缓冲时),因此问题是write
是否线程安全。 POSIX要求write
具有线程安全性(1003.1-2001:2.9.1&2.9.7),通常情况下它是线程安全的。 - JJJMVar
锁是使用futex
实现的(当使用threaded
运行时)。因此,@shachaf 的答案是正确的。 - JJJ