首页 > 解决方案 > 在事件循环中等待未来/协程;外部协程

问题描述

我有一些具有这种结构的代码:

def my_callback():
    loop = asyncio.get_event_loop()
    return loop.run_until_complete(my_coroutine_2())

async def my_coroutine_2():
    return await my_stuff.some_future

async def my_coroutine():
    not_my_code.library_function(my_callback)

在调用的内部my_callbacklibrary_function我需要访问和运行协程代码。

但是,run_until_complete会产生错误:Event loop already running!.

是否有可能完成上面描述的事情?

也就是说,是否有一个普通的函数调用会导致事件循环暂停当前正在执行的任何协程(即 的调用者loop.run_until_complete()),并继续执行其他协程(包括传递给run_until_complete()的协程),直到请求的协程完成,在这种情况下,普通功能会解除阻塞吗?

我认为线程可能会有所帮助,但据我所知,所有协程都必须属于同一个线程。

我该怎么做呢?是否可以?

标签: python-3.xasynchronousconcurrencypython-asynciocoroutine

解决方案


假设外部库是线程安全的,您可以使用run_in_executor. 在等待函数完成时,当前协程将被阻塞,但事件循环将继续运行。

当从另一个线程调用您的回调时,它可以使用run_coroutine_threadsafe将协程提交到(仍然功能齐全的)事件循环,并将结果报告回库:

async def my_coroutine():
    loop = asyncio.get_event_loop()
    await loop.run_in_executor(None, not_my_code.library_function,
                               lambda: my_callback(loop))

def my_callback(loop):
    return asyncio.run_coroutine_threadsafe(my_coroutine_2(), loop)

推荐阅读