[英]How to get a return value from a thread, asynchonously?
我的问题:启动一个线程 function 并异步地对返回的值进行操作
我知道如何:
threading
启动一个带螺纹的 function 。 问题:没有简单的方法可以返回结果我想要实现的类似于 JavaScript 的
aFunctionThatReturnsAPromise()
.then(r => {// do something with the returned value when it is available})
// the code here runs synchronously right after aFunctionThatReturnsAPromise is started
在伪 Python 中,我会考虑类似(修改示例从答案到链接线程)
import time
import concurrent.futures
def foo(bar):
print('hello {}'.format(bar))
time.sleep(10)
return 'foo'
def the_callback(something):
print(f"the thread returned {something}")
with concurrent.futures.ThreadPoolExecutor() as executor:
# submit the threaded call ...
future = executor.submit(foo, 'world!')
# ... and set a callback
future.callback(the_callback, future.result()) # ← this is the made up part
# or, all in one: future = executor.submit(foo, 'world!', callback=the_callback) # in which case the parameters probably would need to be passed the JS way
# the threaded call runs at its pace
# the following line is ran right after the call above
print("after submit")
# after some time (~10 seconds) the callback is finished (and has printed out what was passed to it)
# there should probably be some kind of join() so that the scripts waits until the thread is done
如果可能的话,我想保留线程(它们按照自己的节奏做事,我不在乎它们什么时候完成),而不是asyncio
(我必须在单个线程中明确地await
事情)
您可以使用concurrent.futures
库的add_done_callback ,因此您可以像这样修改您的示例:
def the_callback(something):
print(f"the thread returned {something.result()}")
with concurrent.futures.ThreadPoolExecutor() as executor:
future = executor.submit(foo, 'world!')
future.add_done_callback(the_callback)
您可以使用concurrent.futures.dd_done_callback
,如下所示。 回调必须是一个可调用的,采用单个参数,即Future
实例——它必须从中获取结果,如图所示。 该示例还向其中添加了一些附加信息,回调 function 用于打印其消息。
请注意,回调函数将被同时调用,因此如果涉及共享资源,则应采取通常的互斥预防措施。 示例中没有这样做,因此有时打印的 output 会混乱。
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')
样品 output:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.