VectorVictor VectorVictor - 1 month ago 9
Python Question

Python threads and strings

I am new to threads and multiprocessing. I have some code in which I start a process and I wanted the output to show an active waiting state of something like this

wating....


The code is similiar to this below:

import threading
import time

class ThreadExample(object):

def __init__(self):
self.pause = True
threading.Thread(target=self.second_thread).start()
# Some other processes
print("Waiting", end="")
while self.pause:
time.sleep(1)
print(".", end="")
print("Hooray!")

def second_thread(self):
print("timer started")
time.sleep(3)
self.pause = False
print("timer finished")

if __name__ == "__main__":
ThreadExample()


When I run the code above, I receive the output:

timer started
Do something else..timer finished
.
Hooray!


not a big surprise, except that only the 'timer started' appears at the beginning and the rest of the text appears in an instant at the end.

If I change the line print(".", end="") to print("."), I receive the following output:

timer started
Do something else.
.
timer finished
.
Hooray


where the dots appear in 1 second increments, which was my intention.

Is there a way to get the 'Waiting...' on one line without the end=""?

And secondly I am guessing this is something to do with the internals of the print() function, and if not, should I perform the threading in another manner? I do not think the problem is the GIL as I have tried multiprocess.Process and got the same result.

Answer

This is probably due to print buffering. It is flushed on \n and on some other occasions (like buffer overflow or program exit). Instead of print try this:

import sys

def unbuffered_print(msg):
    sys.stdout.write(msg)
    sys.stdout.flush()

...
unbuffered_print('.')

everywhere.

Comments