[英]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.