【发布时间】:2019-04-20 12:06:00
【问题描述】:
我正在尝试理解 python async/await 并使用 Future 对象来指示函数可以继续。这是一些重现我遇到的问题的代码:
import time, threading, asyncio
loop = asyncio.get_event_loop()
f = loop.create_future()
def resolve(fut):
for i in range(3):
print(i)
time.sleep(1)
fut.set_result(88)
async def wait_on_future(fut):
print('waiting for fut')
await fut
print('done', fut.result())
return fut.result()
threading.Thread(target=resolve, args=(f,)).start()
loop.create_task(wait_on_future(f))
loop.run_forever()
哪个打印:
0
waiting for fut
1
2
请注意,它从不打印'done'。在文档的awaitables 部分中,它说:
当一个 Future 对象被等待时,这意味着协程将等到 Future 在其他地方解决。
我认为调用set_result 是解决Future 的方法。我在这里错过了什么?
注意:如果我在同一个线程中调用 resolve,这可以正常工作。我要解决的实际问题是解决Future 的事件发生在一个线程中。我确实注意到Future 文档说它不是线程安全的。你如何创建一个异步函数来等待另一个线程中发生的事件?
【问题讨论】:
-
"> 我确实注意到 Future 文档说它不是线程安全的。"大多数 asyncio 都不是线程安全的。同时使用 asyncio 和线程通常没有意义。您是否尝试过使用多处理?
-
@CharmingRobot 线程源自用 cython 包装的 C++ 代码。我正在尝试使用这些线程触发的回调来解析某些异步代码中的 Futures。我熟悉多处理;它无助于解决此问题,但感谢您的想法。
-
你看过
run_in_executorasyncio 函数了吗?也许你可以在你的协程中调用 `await run_in_executor(resolve(f))? -
另外,如果你想在不同的线程上安排一个协程,你可以使用
asyncio.run_coroutine_threadsafe。 docs.python.org/3/library/… -
@CharmingRobot 我想
run_coroutine_threadsafe可能对我有用,谢谢你的链接!
标签: python-3.x async-await future