Search code examples
pythonmultithreadingpython-3.xbuffering

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.


Solution

  • 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.