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

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

One way Ive seen is to pass a mutable object, such as a list or a dictionary, to the threads 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 Thread

threads = [None] * 10
results = [None] * 10

for i in range(len(threads)):
    threads[i] = Thread(target=foo, args=(world!, results, i))
    threads[i].start()

# do some other stuff

for 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 Thread

def 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._return

twrv = 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 + baz

from multiprocessing.pool import ThreadPool
pool = ThreadPool(processes=1)

async_result = pool.apply_async(foo, (world, foo)) # tuple of args for foo

# do some other stuff in the main process

return_val = async_result.get()  # get the return value from your function.

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

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.futures

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

Leave a Reply

Your email address will not be published. Required fields are marked *