如何从python中的线程获取返回值?

发布于 2021-02-02 23:21:14

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

关注者
0
被浏览
106
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

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

    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实现的“私有”数据结构…但是它可以工作。

    对于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
    


  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    FWIW,该multiprocessing模块为此类提供了一个不错的接口Pool。而且,如果你要坚持使用线程而不是进程,则可以只使用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.
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看