views:

625

answers:

4

How do I get a thread to return a tuple or any value of my choice back to the parent in Python?

+1  A: 

Well, in the Python threading module, there are condition objects that are associated to locks. One method acquire() will return whatever value is returned from the underlying method. For more information: Python Condition Objects

BenHayden
+6  A: 

I suggest you instantiate a Queue.Queue before starting the thread, and pass it as one of the thread's args: before the thread finishes, it .puts the result on the queue it received as an argument. The parent can .get or .get_nowait it at will.

Queues are generally the best way to arrange thread synchronization and communication in Python: they're intrinsically thread-safe, message-passing vehicles -- the best way to organize multitasking in general!-)

Alex Martelli
+1  A: 

Another approach is to pass a callback function to the thread. This gives a simple, safe and flexible way to return a value to the parent, anytime from the new thread.

# A sample implementation

import threading
import time

class MyThread(threading.Thread):
    def __init__(self, cb):
        threading.Thread.__init__(self)
        self.callback = cb

    def run(self):
        for i in range(10):
            self.callback(i)
            time.sleep(1)


# test

import sys

def count(x):
    print x
    sys.stdout.flush()

t = MyThread(count)
t.start()
Vijay Mathew
The problem with this is that the callback still runs in the child thread, rather than in the original thread.
wilberforce
@wilberforce could you please explain what problems it can cause?
Vijay Mathew
Ok. An example would be if the callback writes to a log file to which the parent thread also writes while the thread is running. Since the callback is running in the child thread there's a risk of the two writes happening at the same time and colliding - you could get garbled or interleaved output, or a crash if the logging framework did some internal bookkeeping. Using a thread-safe queue and having one thread do all the writing would avoid this. These kinds of problems can be nasty because they aren't deterministic - they might only show up in production, and can be difficult to reproduce.
wilberforce
A: 

If you were calling join() to wait for the thread to complete, you could simply attach the result to the Thread instance itself and then retrieve it from the main thread after the join() returns.

On the other hand, you don't tell us how you intend to discover that the thread is done and that the result is available. If you already have a way of doing that, it will probably point you (and us, if you were to tell us) to the best way of getting the results out.

Peter Hansen