Yoshi
Yoshi

Reputation: 115

python thread only prints to stdout after join

I have a python program which I am trying to add a progress bar to. My thread class is:

class ProgressThread(threading.Thread):
    def __init__(self):
        super(ProgressThread, self).__init__()
        self.stoprequest = threading.Event()

    def run(self):
        while not self.stoprequest.is_set():
            print ".",
            time.sleep(5)

    def join(self, timeout=None):
        self.stoprequest.set()
        super(ProgressThread, self).join(timeout)

Then in my main thread I am using the thread class above like this:

progress_thread = ProgressThread()
progress_thread.start()
ret = long_running_method()
progress_thread.join()

The issue I am having is that the dots do not get printed until I call join(). The correct number of dots are there corresponding to the time it takes for long_running_method to complete but I want them to show up one by one just to show the user that the program is not hung.

Upvotes: 2

Views: 2798

Answers (2)

dionyziz
dionyziz

Reputation: 2442

Your code works fine for me in both Python 2.7.8 and 3.4.1 on mac. Here is my testcase:

import threading, time


class ProgressThread(threading.Thread):
   def __init__(self):
       super(ProgressThread, self).__init__()
       self.stoprequest = threading.Event()

   def run(self):
       while not self.stoprequest.is_set():
           print(".")
           time.sleep(1)

   def join(self, timeout=None):
       self.stoprequest.set()
       super(ProgressThread, self).join(timeout)

def long_running_method():
    time.sleep(5)

progress_thread = ProgressThread()
progress_thread.start()
ret = long_running_method()
progress_thread.join()

Could it be an output buffering issue with your terminal or operating system? Try flushing your output:

import sys
sys.stdout.flush()

Upvotes: 2

TheSoundDefense
TheSoundDefense

Reputation: 6935

I believe the issue is that when you use print ".", you're not printing out a newline character (the comma prevents that). By default, stdout is not flushed to the screen until it sees a newline \n character. You can get around this by adding sys.stdout.flush() after the print statement. That will force the output to be printed to screen.

Upvotes: 3

Related Questions