簡體   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