How to get the return value from a thread in python? How to get the return value from a thread in python? python python

How to get the return value from a thread in python?


One way I've seen is to pass a mutable object, such as a list or a dictionary, to the thread's constructor, along with a an index or other identifier of some sort. The thread can then store its results in its dedicated slot in that object. For example:

def foo(bar, result, index):    print 'hello {0}'.format(bar)    result[index] = "foo"from threading import Threadthreads = [None] * 10results = [None] * 10for i in range(len(threads)):    threads[i] = Thread(target=foo, args=('world!', results, i))    threads[i].start()# do some other stufffor i in range(len(threads)):    threads[i].join()print " ".join(results)  # what sound does a metasyntactic locomotive make?

If you really want join() to return the return value of the called function, you can do this with a Thread subclass like the following:

from threading import Threaddef foo(bar):    print 'hello {0}'.format(bar)    return "foo"class ThreadWithReturnValue(Thread):    def __init__(self, group=None, target=None, name=None,                 args=(), kwargs={}, Verbose=None):        Thread.__init__(self, group, target, name, args, kwargs, Verbose)        self._return = None    def run(self):        if self._Thread__target is not None:            self._return = self._Thread__target(*self._Thread__args,                                                **self._Thread__kwargs)    def join(self):        Thread.join(self)        return self._returntwrv = ThreadWithReturnValue(target=foo, args=('world!',))twrv.start()print twrv.join()   # prints foo

That gets a little hairy because of some name mangling, and it accesses "private" data structures that are specific to Thread implementation... but it works.

For python3

class ThreadWithReturnValue(Thread):    def __init__(self, group=None, target=None, name=None,                 args=(), kwargs={}, Verbose=None):        Thread.__init__(self, group, target, name, args, kwargs)        self._return = None    def run(self):        print(type(self._target))        if self._target is not None:            self._return = self._target(*self._args,                                                **self._kwargs)    def join(self, *args):        Thread.join(self, *args)        return self._return


FWIW, the multiprocessing module has a nice interface for this using the Pool class. And if you want to stick with threads rather than processes, you can just use the multiprocessing.pool.ThreadPool class as a drop-in replacement.

def foo(bar, baz):  print 'hello {0}'.format(bar)  return 'foo' + bazfrom multiprocessing.pool import ThreadPoolpool = ThreadPool(processes=1)async_result = pool.apply_async(foo, ('world', 'foo')) # tuple of args for foo# do some other stuff in the main processreturn_val = async_result.get()  # get the return value from your function.


In Python 3.2+, stdlib concurrent.futures module provides a higher level API to threading, including passing return values or exceptions from a worker thread back to the main thread:

import concurrent.futuresdef foo(bar):    print('hello {}'.format(bar))    return 'foo'with concurrent.futures.ThreadPoolExecutor() as executor:    future = executor.submit(foo, 'world!')    return_value = future.result()    print(return_value)