Return value from thread

Viewed 99672

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

13 Answers

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!-)

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.

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()

For easy programs the above answeres look a little bit like overkill to me. I would en-nicen the mutable approach:

class RetVal:
 def __init__(self):
   self.result = None


def threadfunc(retVal):
  retVal.result = "your return value"

retVal = RetVal()
thread = Thread(target = threadfunc, args = (retVal))

thread.start()
thread.join()
print(retVal.result)

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

Here is a code which implements multi-threading.

Thread 1 is adding numbers from 10 to 20. Thread 2 is adding numbers from 21 to 30.

Finally the output is returned to the main program where it can perform final addition. (not shown in this program) but you can use a numpy call.

import threading
import os
import queue

def task1(num, queue): 
    print("\n Current thread: {}".format(threading.current_thread().name)) 
    count = 0
    sum1 = 0
    while count <= 10:
        sum1 = sum1 + num
        num = num + 1
        count = count + 1
    print('\n'+str(sum1))
    queue.put(sum1)


if __name__ == "__main__":

    queue = queue.Queue()

    # print ID of current process 
    print("\n Process ID is: {}".format(os.getpid())) 

    # print name of main thread 
    print("\n Main thread is: {}".format(threading.main_thread().name)) 

    # creating threads 
    t1 = threading.Thread(target=task1, name='t1',args=[10,queue]) 
    t2 = threading.Thread(target=task1, name='t2',args=[21,queue])

    #Store thread names in a list
    pool = [t1,t2]

    #Used to store temporary values
    thread_results = []

    # starting threads
    #Start all threads in thread pool
    for thread in pool:
        thread.start()
        response = queue.get()
        thread_results.append(response)

    #Kill all threads
    for thread in pool:
        thread.join()

    print(thread_results)
Related