在Python中,flushing是如何工作的,原因是什么?

In Python, how does flushing work and what is the reason?

我有一个包含打印语句的小型多线程程序。 如果我没有将 end 更改为 \n 以外的其他字符,它会完美地工作。 如果我想使用其他字符而不是 \n,我需要将 flush 设置为 True

所以我的问题是冲洗是如何工作的,原因是什么?

#!/usr/bin/env python -u
# -*- coding: utf-8 -*-
from threading import Thread
from queue import Queue
from time import sleep


def do_stuff(task):
    while not task.empty():
        sleep(1)
        print(task.get())  # works well
        # print(task.get(), end='\n')  # works well
        # print(task.get(), end=',', flush=True)  # works well
        # print(task.get(), end=',')  # works badly
        task.task_done()


q = Queue(maxsize=0)
for x in range(0, 5):
    q.put(x)

num_threads = 2

for i in range(num_threads):
    worker = Thread(target=do_stuff, args=(q,))
    worker.setDaemon(True)
    worker.start()

q.join()

当您在 Python 中打印并使用逗号作为最后一个字符(不是字符而是分隔符)时,输出不会被刷新,因为它正在等待另一个打印语句。这就是打印命令中逗号的作用。如果您不将逗号添加到打印命令,它应该刷新并在此过程中创建一个新行,实际上相反,它创建一个换行符并因此刷新。

    print(task.get(), end=',') 

将打印时不带换行符,并等待下一次创建新行的打印,然后再刷新缓冲区。

 print(task.get())  
 print(task.get(), end='\n')  # works well

将打印包括新行在内的内容并刷新缓冲区。

这是许多控制台输出应用程序中非常常见的做法,与您在 C 和 C++ 中获得的行为完全相同。换行符用作缓冲区清空的标志,如果缓冲区在每个字符后清空,则会消耗太多 cpu.

 print(task.get(), end=',', flush=True) 

上面的工作是因为我们明确地说要刷新缓冲区。不会有换行符,但打印语句会刷新缓冲区并立即打印。