Python的线程模块。如何从Thread类实例返回函数输出?

7 浏览
0 Comments

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日
0
0 Comments

顺便提一句,使用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.

0
0 Comments

一种我见过的方法是将可变对象(如列表或字典)与某种索引或其他标识符一起传递给线程的构造函数。然后线程可以将其结果存储在该对象的专用槽中。例如:

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

0