【问题标题】:await seems to block on asycio.Futureawait 似乎阻止了 asyncio.Future
【发布时间】: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_executor asyncio 函数了吗?也许你可以在你的协程中调用 `await run_in_executor(resolve(f))?
  • 另外,如果你想在不同的线程上安排一个协程,你可以使用asyncio.run_coroutine_threadsafedocs.python.org/3/library/…
  • @CharmingRobot 我想run_coroutine_threadsafe 可能对我有用,谢谢你的链接!

标签: python-3.x async-await future


【解决方案1】:

好的,感谢@CharmingRobot 对run_coroutine_threadsafe 的评论,我找到了这个解决方案:

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)
    async def a_resolve():
        fut.set_result(88)
    asyncio.run_coroutine_threadsafe(a_resolve(), loop)

async def wait_on_future(fut):
    print('waiting for fut')
    return await fut

async def print_future():
    print('got the future! value:', await wait_on_future(f))

loop.create_task(print_future())
threading.Thread(target=resolve, args=(f,)).start()
loop.run_forever()

哪个打印:

0
waiting for fut
1
2
got the future! value: 88

这正是我想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2020-03-03
    • 2020-04-29
    • 2014-02-03
    • 2013-06-22
    • 2019-09-30
    • 1970-01-01
    相关资源
    最近更新 更多