我已经在各种邮件列表和论坛上看到人们不断提到Python 3中的打印功能是线程安全的。根据我自己的测试,我认为没有理由怀疑。
import threading
import time
import random
def worker(letter):
print(letter * 50)
threads = [threading.Thread(target=worker, args=(let,)) for let in "ABCDEFGHIJ"]
for t in threads:
t.start()
for t in threads:
t.join()
当我使用Python 3运行它时,即使某些行可能出现故障,它们仍然总是在自己的行上。但是,对于Python 2,输出是相当零星的。有些线连接在一起或缩进。我from __future__ import print_function
我只是想了解为什么会出现这种情况?
答案 0 :(得分:1)
对于Python 3.7:print()
函数是builtin,默认情况下,它会将输出发送到sys.stdout
,documentation of which说:
交互式时,stdout和stderr流是行缓冲的。 否则,它们像常规文本文件一样被块缓冲。您可以 使用-u命令行选项覆盖此值。
因此,实际上是交互式模式和sys.stderr
的组合,它负责print
函数的行为,如示例所示。
如果您将示例程序中的worker
函数更改为
def worker(letter):
print(letter*25, letter*25, sep='\n')
然后我们得到类似于以下输出的输出,该输出清楚地表明print
本身不是线程安全的,您可以期望的是各个行不会相互交错。
DDDDDDDDDDDDDDDDDDDDDDDDDJJJJJJJJJJJJJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJJJJJJJJJJJ
DDDDDDDDDDDDDDDDDDDDDDDDDGGGGGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGGGGGGGGGAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHHHHHHHHH
FFFFFFFFFFFFFFFFFFFFFFFFF
IIIIIIIIIIIIIIIIIIIIIIIIICCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCC
IIIIIIIIIIIIIIIIIIIIIIIII
EEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFF
BBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBB
因此print
的线程安全最终取决于所使用的缓冲策略。