是什么让Python3的打印功能线程安全?

时间:2017-03-17 22:11:34

标签: multithreading printing cpython

我已经在各种邮件列表和论坛上看到人们不断提到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

的情况也是如此

我只是想了解为什么会出现这种情况?

1 个答案:

答案 0 :(得分:1)

对于Python 3.7:print()函数是builtin,默认情况下,它会将输出发送到sys.stdoutdocumentation 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的线程安全最终取决于所使用的缓冲策略。