是什么使Python3的打印函数线程安全? [英] What makes Python3's print function thread safe?
问题描述
我在各种邮件列表和论坛上看到人们不断提到Python 3中的打印功能是线程安全的。从我自己的测试中,我看不出有什么疑问。
导入线程
导入时间
导入随机
def worker(字母):
print(字母* 50)
线程= [threading.Thread(target = worker,args = (let,))对于 ABCDEFGHIJ中的let:
对于线程中的t:
t.start()
对于线程中的t:
t.join()
当我使用Python 3运行它时,即使某些行可能乱序,它们仍然总是走自己的路。但是,对于Python 2,输出是相当零星的。有些线连接在一起或缩进。当我从__future__导入print_function
- Python 2.7 builtin_print <-线程不安全
- Python 3.6 builtin_print <-
我只是想了解为什么会这样?
对于Python 3.7: print()
函数是内置,默认情况下它将输出发送到 sys.stdout
, 其中的文档以及其他内容:
交互时,stdout和stderr流是行缓冲的。
否则,它们将像常规文本文件一样被块缓冲。您可以使用-u命令行选项
覆盖此值。
因此,它实际上是交互式模式和<$ c $的组合c> sys.stderr 负责 print
函数的行为,如示例所示。
如果将示例程序中的 worker
函数更改为
def worker(letter):
print(字母* 25,letter * 25,sep ='\n')
然后我们得到类似于以下内容的输出,该输出清楚地表明 print
本身不是线程安全的,您可以期望的是单独的行没有得到交错彼此。
DDDDDDDDDDDDDDDDDDDDDDDDDJJJJJJJJJJJJJJJJJJJJJJJJJ
由使用的缓冲策略决定。
JJJJJJJJJJJJJJJJJJJJJJJJJ
DDDDDDDDDDDDDDDDDDDDDDDDDGGGGGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGGGGGGGGGAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHHHHHHHHH
FFFFFFFFFFFFFFFFFFFFFFFFFFF
IIIIIIIIIIIIIIIIIIIIIIIIICCCCCCCCCCCCCCCCCCCCCCCCCCCbEEbEEb EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFF
BBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBI've seen on various mailing lists and forums that people keep mentioning that the print function in Python 3 is thread safe. From my own testing, I see no reason to doubt that.
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()
When I run it with Python 3, even though some of the lines may be out of order, they are still always on their own lines. With Python 2, however, the output is fairly sporadic. Some lines are joined together or indented. This is also the case when I
from __future__ import print_function
- Python 2.7 builtin_print <- not thread safe
- Python 3.6 builtin_print <- thread safe?
I'm just trying to understand WHY this is the case?
For Python 3.7: The print()
function is a builtin, it by default sends output to sys.stdout
, the documentation of which says, among other things:
When interactive, stdout and stderr streams are line-buffered. Otherwise, they are block-buffered like regular text files. You can override this value with the -u command-line option.
So its really the combination of interactive mode and sys.stderr
that is responsible for the behaviour of the print
function as demonstrated in the example.
And we can get closer to the truth if the worker
function in your example program is changed to
def worker(letter):
print(letter*25, letter*25, sep='\n')
then we get outputs similar to the one below, which clearly shows that print
in itself is not thread safe, what you can expect is that individual lines do not get interleaved with each other.
DDDDDDDDDDDDDDDDDDDDDDDDDJJJJJJJJJJJJJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJJJJJJJJJJJ
DDDDDDDDDDDDDDDDDDDDDDDDDGGGGGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGGGGGGGGGAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHHHHHHHH
HHHHHHHHHHHHHHHHHHHHHHHHH
FFFFFFFFFFFFFFFFFFFFFFFFF
IIIIIIIIIIIIIIIIIIIIIIIIICCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCC
IIIIIIIIIIIIIIIIIIIIIIIII
EEEEEEEEEEEEEEEEEEEEEEEEE
EEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFF
BBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBB
So ultimately thread safety of print
is determined by the buffering strategy used.
这篇关于是什么使Python3的打印函数线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!