簡體   English   中英

如何在 Python/Tornado 中使用 run_in_executor 方法調用異步函數?

[英]How do I call an async function with method run_in_executor in Python/Tornado?

我有一個 python 文件,其中有一個帶有以下相關代碼的龍卷風請求處理程序類:

executor = concurrent.futures.ThreadPoolExecutor(max_workers = 20)
from tornado.platform.asyncio import AnyThreadEventLoopPolicy
asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

class MainHandler(tornado.web.RequestHandler):
   async def connect(self):
      # some code
      loop = asyncio.get_event_loop()
      await loop.run_in_executor(executor, self.connect_function)

   async def connect_function(self):
      #some code with an await operation somewhere here

所以我的主要目標是能夠將請求處理程序與線程一起使用。 我發現我可以做到這一點的方法是使用run_in_executor方法。 這里的問題是,在connect方法中,我想等待也是異步的connect_function結束,這通常會引發錯誤: RuntimeWarning: coroutine 'MainHandler.connect_function' was never awaited 我的問題是,如果這是我可以讓線程在這個龍卷風請求處理程序中工作的唯一方法,如果是這樣,如果有一種方法我可以使用run_in_executor方法等待異步函數的執行。

您不能在 ThreadPoolExecutor 中運行異步函數(除非您還在那里運行另一個事件循環,這通常不是您想要的)。 您可以在主事件循環上安排一個回調,然后在線程上等待它,但這很復雜。 作為一般規則,當您使用像 Tornado 這樣的異步框架時,您希望盡可能地留在事件循環線程上,並且僅在必要時將事情發送到 ThreadPoolExecutor(然后讓這些函數return到主線程而不是嘗試從線程回調異步代碼)。

我認為異步處理隨着版本 6 的變化而改變。

所以一些例子/howtos可能會產生誤導。 您可能想查看 tornado 文檔頁面以獲取最新示例。 這里向下滾動異步代碼示例

好的,簡單的英語。

fetch_reference_fx (它是一個異步函數)為例,

代替:

fetches = [
                    one_loop.run_in_executor(None, fetch_reference_fx, price_sources, vwap_num_levels, self.app_context.logger),
                ]
results = await asyncio.gather(*fetches)

改為這樣做:

fetches = [
                    fetch_reference_fx(price_sources, vwap_num_levels, self.app_context.logger)
                ]
results = await asyncio.gather(*fetches)

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM