【发布时间】:2019-12-10 08:21:59
【问题描述】:
我试图理解python asyncio的call_soon_threadsafe API,但是失败了,下面的示例代码,如果我的simple协程想要返回一些东西,我应该如何从调用方获取返回值?
import time
import asyncio as aio
import uvloop
from threading import Thread
aio.set_event_loop_policy(uvloop.EventLoopPolicy())
async def simple(a, fut:aio.Future):
await aio.sleep(a)
return fut.set_result(a)
def delegator(loop):
aio.set_event_loop(loop)
loop.run_forever()
loop_exec = aio.new_event_loop()
t = Thread(target=delegator, args=(loop_exec,))
t.start()
if __name__ == '__main__':
start_time = time.time()
fut = loop_exec.create_future() # tried to get back returned value by future
handle = loop_exec.call_soon_threadsafe(aio.ensure_future, simple(3, fut))
res = aio.wait_for(fut, 10)
print('Time consumed: {}s'.format(time.time() - start_time))
print('>>>>>>>>>>', res)
# Output
Time consumed: 3.2901763916015625e-05s
>>>>>>>>>> <generator object wait_for at 0x110bb9b48>
如您所见,我试图通过将未来传递给在不同线程中运行的协程来取回返回值,但仍然不知道如何正确获取它。
基本上两个问题:
- 使用上面的示例代码如何从调用方取回返回值?
- 这个
call_soon_threadsafe的实际用例是什么,只是觉得run_coroutine_threadsafe使用起来更方便,几乎可以涵盖这种不同线程协程交互中我能想到的所有情况。
【问题讨论】:
-
要回答问题 1,您必须使用 concurrent.futures.Future 而不是
loop_exec.create_future并将aio.wait_for(fut, 10)替换为fut.result()。这基本上就是run_couroutine_threadsafe所做的。
标签: python python-3.x python-asyncio coroutine