Python 如何从线程异步获取返回值?

Python 如何从线程异步获取返回值?,python,python-3.x,multithreading,callback,asynccallback,Python,Python 3.x,Multithreading,Callback,Asynccallback,我的问题:启动一个线程函数,并对返回值执行异步操作 我知道如何: 使用线程化启动线程化函数。问题是:没有简单的方法可以恢复结果 从一个线程函数。问题是:它是同步的 我想要实现的与JavaScript类似 aFunctionThatReturnsAPromise() .then(r => {// do something with the returned value when it is available}) // the code here runs synchronously

我的问题:启动一个线程函数,并对返回值执行异步操作

我知道如何:

  • 使用
    线程化
    启动线程化函数。问题是:没有简单的方法可以恢复结果
  • 从一个线程函数。问题是:它是同步的
我想要实现的与JavaScript类似

aFunctionThatReturnsAPromise()
  .then(r => {// do something with the returned value when it is available})
// the code here runs synchronously right after aFunctionThatReturnsAPromise is started
在pseudo-Python中,我会考虑以下内容(将示例从修改为链接线程)

如果可能的话,我想继续使用线程(它们以自己的速度做事情,我不在乎什么时候完成),而不是
asyncio
(我必须在单个线程中显式地
等待
事情)

您可以使用
concurrent.futures
库,这样您就可以修改您的示例:

def_回调(某物):
print(f“线程返回{something.result()}”)
以concurrent.futures.ThreadPoolExecutor()作为执行器:
future=executor.submit(foo'world!')
future.add_done_回调(_回调)
您可以按如下所示使用。回调必须是一个可调用的函数,使用单个参数
Future
实例,并且它必须从中获得结果,如图所示。该示例还向其中添加了回调函数用于打印其消息的一些附加信息

请注意,回调函数将被并发调用,因此如果涉及共享资源,则应采取通常的互斥预防措施。示例中没有这样做,因此有时打印输出会混乱

from concurrent import futures
import random
import time

def foo(bar, delay):
    print(f'hello {bar} - {delay}')
    time.sleep(delay)
    return bar

def the_callback(fn):
    if fn.cancelled():
        print(f'args {fn.args}: canceled')
    elif fn.done():
        error = fn.exception()
        if error:
            print(f'args {fn.args}: caused error {erro}')
        else:
            print(f'args {fn.args}: returned: {fn.result()}')

with futures.ThreadPoolExecutor(max_workers=2) as executor:
    for name in ('foo', 'bar', 'bas'):
        delay = random.randint(1, 5)
        f = executor.submit(foo, name, delay)
        f.args = name, delay
        f.add_done_callback(the_callback)

print('fini')
样本输出:

hello foo - 5
hello bar - 3
args ('bar', 3): returned: bar
hello bas - 4
args ('foo', 5): returned: foo
args ('bas', 4): returned: bas
fini
hello foo - 5
hello bar - 3
args ('bar', 3): returned: bar
hello bas - 4
args ('foo', 5): returned: foo
args ('bas', 4): returned: bas
fini