Duncan's method is probably the best and is what I would recommend. I've been mildly annoyed by the lack of "wait for next completed thread to complete" before, though, so I just wrote this up to try it out. Seems to work. Simply use MWThread in place of threading.thread and you get this new wait_for_thread function.
The global variables are a bit klunky; an alternative would be to make them class-level variables. But if this is hidden in a module (mwthread.py or whatever) it should be fine either way.
#! /usr/bin/env python # Example of how to "wait for" / join whichever threads is/are done, # in (more or less) the order they're done. import threading from collections import deque _monitored_threads = [] _exited_threads = deque() _lock = threading.Lock() _cond = threading.Condition(_lock) class MWThread(threading.Thread): """ multi-wait-able thread, or monitored-wait-able thread """ def run(self): tid = threading.current_thread() try: with _lock: _monitored_threads.append(tid) super(MWThread, self).run() finally: with _lock: _monitored_threads.remove(tid) _exited_threads.append(tid) _cond.notifyAll() def wait_for_thread(timeout=None): """ Wait for some thread(s) to have finished, with optional timeout. Return the first finished thread instance (which is removed from the finished-threads queue). If there are no unfinished threads this returns None without waiting. """ with _cond: if not _exited_threads and _monitored_threads: _cond.wait(timeout) if _exited_threads: result = _exited_threads.popleft() else: result = None return result def main(): print 'testing this stuff' def func(i): import time, random sleeptime = (random.random() * 2) + 1 print 'thread', i, 'starting - sleep for', sleeptime time.sleep(sleeptime) print 'thread', i, 'finished' threads = [MWThread(target=func, args=(i,)) for i in range(3)] for th in threads: th.start() i = 0 while i < 3: print 'main: wait up to .5 sec' th = wait_for_thread(.5) if th: print 'main: got', th th.join() i += 1 else: print 'main: timeout' print 'I think I collected them all' print 'result of wait_for_thread():' print wait_for_thread() if __name__ == '__main__': main()