Python的线程模块。如何从Thread类实例返回函数输出?
Python的线程模块。如何从Thread类实例返回函数输出?
下面的函数foo
返回一个字符串\'foo\'
。我如何获得从线程目标返回的值\'foo\'
?
from threading import Thread def foo(bar): print('hello {}'.format(bar)) return 'foo' thread = Thread(target=foo, args=('world!',)) thread.start() return_value = thread.join()
上面展示的“显而易见的方法”不能工作:thread.join()
返回None
。
admin 更改状态以发布 2023年5月20日
顺便提一句,使用Pool
类,multiprocessing
模块对于这一点有一个不错的接口。如果你想要坚持使用线程而不是进程,你可以使用multiprocessing.pool.ThreadPool
类来代替。
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.
一种我见过的方法是将可变对象(如列表或字典)与某种索引或其他标识符一起传递给线程的构造函数。然后线程可以将其结果存储在该对象的专用槽中。例如:
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?
如果您真的想让 join()
返回被调用函数的返回值,您可以使用类似以下的 Thread
子类来实现:
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
由于姓名混淆,访问了特定于 Thread
实现的“私有”数据结构,这有点棘手...但它起作用。
针对Python 3:
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): 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