Search code examples
python-3.xpython-multithreading

Thread wait in Python till function execution is done without using join() method


I have a thread in which I have passed function. I now want to wait till the function is done executing. Can I make it wait till the function passed to thread is executed fully without using join().

Like I have a sample code snippet.

# Some code
.
def sampleFunc():
    # func code
    .
    .
    .
.
.
.
thread = threading.Thread(target=sampleFunc, arg=())
thread.start()

print('After thread')
.
.
.

I have something like this and I am using in tkinter but the print() prints 'After Thread' before the thread is completely executed. I want to run the code after the thread is executed fully. If I use join() it is going to freeze the tkinter. Is there any way to achieve this. I am open to suggestions if you have any. Thanks


Solution

  • If you do not want to add the print() at the end of your sampleFunc(), you can do one of the following things.

    1. Subclass the Thread() and call the sampleFunc() inside the run() method like this:
    
    import threading
    
    class MyThread (threading.Thread):
        def run (self):
            sampleFunc()
            print("Sample func done")
    
    thread = MyThread()
    thread.start()
    
    2. If you need it to tell you when the thread is almost completely done, then override the internal bootstraping method. In this case you can continue using your variant of the Thread() as before.
    
    import threading
    
    class Thread (threading.Thread):
        def _bootstrap (self):
            # Note that this method is called __bootstrap() in Python 2.x
            try:
                threading.Thread._bootstrap(self)
            except:
                print("Thread ended with an exception")
                raise
            print("Thread ended properly")
    
    thread = Thread(target=sampleFunc, args=())
    thread.start()
    
    Someone will probably tell me that above shouldn't be done and that all that could have been achieved within the run() method, but I'll still stick with this solution. It leaves you space to subclass this Thread() version and implement different run()s as well as giving the thread function using target argument of a constructor.