Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python threading, how I can I track a thread's completion?

I've a python program that spawns a number of threads. These threads last anywhere between 2 seconds to 30 seconds. In the main thread I want to track whenever each thread completes and print a message. If I just sequentially .join() all threads and the first thread lasts 30 seconds and others complete much sooner, I wouldn't be able to print a message sooner -- all messages will be printed after 30 seconds.

Basically I want to block until any thread completes. As soon as a thread completes, print a message about it and go back to blocking if any other threads are still alive. If all threads are done then exit program.

One way I could think of is to have a queue that is passed to all the threads and block on queue.get(). Whenever a message is received from the queue, print it, check if any other threads are alive using threading.active_count() and if so, go back to blocking on queue.get(). This would work but here all the threads need to follow the discipline of sending a message to the queue before terminating.

I'm wonder if this is the conventional way of achieving this behavior or are there any other / better ways ?

like image 743
0cd Avatar asked May 03 '12 23:05

0cd


People also ask

How do I monitor a thread in Python?

This can be achieved by creating a new thread instance and using the “target” argument to specify the watchdog function. The watchdog can be given an appropriate name, like “Watchdog” and be configured to be a daemon thread by setting the “daemon” argument to True.

How do you check if a thread is done Python?

Once the thread's activity is started, the thread is considered 'alive'. It stops being alive when its run() method terminates – either normally, or by raising an unhandled exception. The is_alive() method tests whether the thread is alive.

How do you get the thread return value?

There are two main ways to return values from a thread, they are: Extend threading. Thread and store data in instance variables. Store data in global variables.


2 Answers

Here's a variation on @detly's answer that lets you specify the messages from your main thread, instead of printing them from your target functions. This creates a wrapper function which calls your target and then prints a message before terminating. You could modify this to perform any kind of standard cleanup after each thread completes.

#!/usr/bin/python

import threading
import time

def target1():
    time.sleep(0.1)
    print "target1 running"
    time.sleep(4)

def target2():
    time.sleep(0.1)
    print "target2 running"
    time.sleep(2)

def launch_thread_with_message(target, message, args=[], kwargs={}):
    def target_with_msg(*args, **kwargs):
        target(*args, **kwargs)
        print message
    thread = threading.Thread(target=target_with_msg, args=args, kwargs=kwargs)
    thread.start()
    return thread

if __name__ == '__main__':
    thread1 = launch_thread_with_message(target1, "finished target1")
    thread2 = launch_thread_with_message(target2, "finished target2")

    print "main: launched all threads"

    thread1.join()
    thread2.join()

    print "main: finished all threads"
like image 100
Matthias Fripp Avatar answered Nov 10 '22 01:11

Matthias Fripp


The thread needs to be checked using the Thread.is_alive() call.

like image 29
letitbee Avatar answered Nov 10 '22 00:11

letitbee