gpt4 book ai didi

python - print() 中的结束 ='...' 键不是线程安全的?

转载 作者:太空狗 更新时间:2023-10-30 01:19:00 26 4
gpt4 key购买 nike

通过下面的代码,我尝试使用 ThreadPoolExecutor 在 jupyter-notebook 上并行打印一堆东西。请注意,使用函数 show() 时,输出不是您通常所期望的。

from concurrent.futures import ThreadPoolExecutor
import sys

items = ['A','B','C','D','E','F',
'G','H','I','J','K','L',
'M','N','O','P','Q','R',
'S','T','U','V','W','X','Y','Z']

def show(name):
print(name, end=' ')

with ThreadPoolExecutor(10) as executor:
executor.map(show, items)

# This outputs
# AB C D E F G H I J KLMNOP QR STU VW XY Z

但是当我尝试使用 sys.stdout.write() 时,我没有得到这种行为。

def show2(name):
sys.stdout.write(name + ' ')

with ThreadPoolExecutor(10) as executor:
executor.map(show2, items)

# This gives
# A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

奇怪的是,我在 jupyter notebook 上以及通过编写 .py 文件并运行它都进行了尝试。但是对于后者,我似乎没有遇到这个问题。我尝试搜索,但我得到的只是 python-3.x 中的 print() 线程安全的。如果它确实是线程安全的,谁能解释为什么会这样?

最佳答案

实际上不需要指定 end 来公开它;即使只是执行 print(name) 有时也会导致字母彼此相邻:

A
B
C
D
EF
G

H
I

即使 flush=True 也无法修复它。

打印功能在CPython中实现here ,并且是用 C 语言编写的。有趣的是:

for (i = 0; i < nargs; i++) {
if (i > 0) {
if (sep == NULL)
err = PyFile_WriteString(" ", file);
else
err = PyFile_WriteObject(sep, file,
Py_PRINT_RAW);
if (err)
return NULL;
}
err = PyFile_WriteObject(args[i], file, Py_PRINT_RAW);
if (err)
return NULL;
}

if (end == NULL)
err = PyFile_WriteString("\n", file);
else
err = PyFile_WriteObject(end, file, Py_PRINT_RAW);

您可以看到它为每个参数调用一次 PyFile_WriteObject(如果指定,则为 sep),然后为 end 再调用一次> 参数(PyFile_WriteString 基本上只是 PyFile_WriteObject 的包装器,它采用 const char* 而不是 PyObject) – 我假设最终有机会在这些调用之间的某处进行上下文切换。

每次调用 PyFile_WriteString 本质上与调用(在 Python 中)sys.stdout.write 相同,这可以解释为什么在执行 sys.stdout.write(name + ' ');如果您改为这样做:

sys.stdout.write(name)
sys.stdout.write(" ")

这更像是 print 函数本身所做的事情,这也解释了为什么 print(name + "", end="") 也能工作。

关于python - print() 中的结束 ='...' 键不是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50551637/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com