简体   繁体   English

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

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

It seems that python's asyncio is an all-or-nothing kind of deal.似乎 python 的 asyncio 是一种全有或全无的交易。 Specifically it seems to force full call stack to be async-aware.具体来说,它似乎强制完整的调用堆栈是异步感知的。

Here is an example:下面是一个例子:

Let's assume that there is an algorithm implemented by function a() .让我们假设有一个由函数a()实现的算法。
That algorithm calls function b() .该算法调用函数b()

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

Now let's assume that function b() might be implemented differently in different environments and one might want to call a() inside an async event loop (with loop.call_soon() ) with b() calling some asyncio-aware code:现在让我们假设函数B()可能会在不同的环境不同的方式实现,一个可能要调用一个()的异步事件循环中(与loop.call_soon())B()调用一些ASYNCIO数据的相关代码:

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

Using existing event loop seems to be explicitly prohibited... So, are there methods to implement this functionality without forcing the full stack ( a() and b() ) to be explicitly defined as async coroutines?似乎明确禁止使用现有的事件循环......那么,是否有方法可以在不强制将完整堆栈( a()b() )明确定义为异步协程的情况下实现此功能?

Although taken at face value asyncio is an all-or-nothing deal, there are still two escape hatches that can help when dealing with legacy or heterogenous environment:尽管从表面上看 asyncio一个全有或全无的交易,但仍有两个逃生舱口可以在处理遗留或异构环境时提供帮助:

  • Within asyncio, you can await loop.run_in_executor(callable, args...) to evaluate sync code in another thread, suspending the current coroutine until the result is ready.在 asyncio 中,您可以 await loop.run_in_executor(callable, args...)评估另一个线程中的同步代码,暂停当前协程直到结果准备好。

  • Outside asyncio, you can use asyncio.run_coroutine_threadsafe() to submit a coroutine to an event loop running in another thread.在 asyncio 之外,您可以使用asyncio.run_coroutine_threadsafe()将协程提交到在另一个线程中运行的事件循环。 It immediately returns returns a concurrent.futures future which has a blocking result() method that blocks the current thread without adversely affecting the event loop.它立即返回一个concurrent.futures未来,它有一个阻塞result()方法,可以阻塞当前线程而不会对事件循环产生不利影响。 (The use of run_coroutine_threadsafe requires starting an event loop in a dedicated thread beforehand.) (使用run_coroutine_threadsafe需要事先在专用线程中启动事件循环。)

With those two tools at your disposal, it is not that hard to mix asyncio and classic synchronous code.有了这两个工具供您使用,混合 asyncio 和经典同步代码并不难。

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

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