Zhang LongQI
Zhang LongQI

Reputation: 494

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

I have a small multithread program including print statement. It works perfectly if I did not change the end to other characters except \n. If I want to use other characters instead of \n, I will need to set flush to True.

So my question is how flushing works and what the reason is?

#!/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()

Upvotes: 4

Views: 2347

Answers (1)

Niki van Stein
Niki van Stein

Reputation: 10724

When you print in Python and use as last character a comma (not as character but as separation sign), the output does not get flushed because it is waiting for another print statement. This is the function of the comma in the print command. If you do not add the comma to the print command it should flush and create a new line in the process, actually the other way around, it creates a newline and therefor flushes.

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

Will print without newline and waits for the next print that will create a new line, before flushing the buffer.

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

Will print something including a new line and flushes the buffer.

This is very common practice in many console output applications, exactly the same behaviour you get with C and C++. The newline is used as a sign to the buffer to empty, if the buffer would empty after each character it would consume way too much cpu.

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

The above works because we say explicitly to flush the buffer. There will be no newline but the print statement will flush the buffer and therefor print immediately.

Upvotes: 4

Related Questions