繁体   English   中英

asyncio:如何在不强制完全暴露于 asyncio 的情况下组合同步代码

[英]asyncio: how to combine sync code without forcing full exposure to asyncio

似乎 python 的 asyncio 是一种全有或全无的交易。 具体来说,它似乎强制完整的调用堆栈是异步感知的。

下面是一个例子:

让我们假设有一个由函数a()实现的算法。
该算法调用函数b()

def a(b):
  for i in ...:
    # do smth...
    res = b()
    # do smth more ...

现在让我们假设函数B()可能会在不同的环境不同的方式实现,一个可能要调用一个()的异步事件循环中(与loop.call_soon())B()调用一些ASYNCIO数据的相关代码:

def b():
   await .... # this forces b() to be declared async.

似乎明确禁止使用现有的事件循环......那么,是否有方法可以在不强制将完整堆栈( a()b() )明确定义为异步协程的情况下实现此功能?

尽管从表面上看 asyncio一个全有或全无的交易,但仍有两个逃生舱口可以在处理遗留或异构环境时提供帮助:

  • 在 asyncio 中,您可以 await loop.run_in_executor(callable, args...)评估另一个线程中的同步代码,暂停当前协程直到结果准备好。

  • 在 asyncio 之外,您可以使用asyncio.run_coroutine_threadsafe()将协程提交到在另一个线程中运行的事件循环。 它立即返回一个concurrent.futures未来,它有一个阻塞result()方法,可以阻塞当前线程而不会对事件循环产生不利影响。 (使用run_coroutine_threadsafe需要事先在专用线程中启动事件循环。)

有了这两个工具供您使用,混合 asyncio 和经典同步代码并不难。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM