簡體   English   中英

在沒有 asyncio.get_event_loop() 的 run_in_executor 的異步方法中使用線程池

[英]Using Threadpool in an Async method without run_in_executor of asyncio.get_event_loop()

以下是我的代碼,它使用Thread Pool from Concurrent.Futures Package異步方法運行長 IO 操作,如下所示:

# io_bound/threaded.py
import concurrent.futures as futures
import requests
import threading
import time
import asyncio

data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

def sleepy(n):
    time.sleep(n//2)
    return n*2

async def ExecuteSleep():
    l = len(data)
    results = []
    # Submit needs explicit mapping of I/p and O/p
    # Output may not be in the same Order
    with futures.ThreadPoolExecutor(max_workers=l) as executor:
        result_futures = {d:executor.submit(sleepy,d) for d in data}
        results = {d:result_futures[d].result() for d in data}
    
    return results

if __name__ == '__main__':
    print("Starting ...")
    t1 = time.time()
    result  = asyncio.run(ExecuteSleep())
    print(result)
    print("Finished ...")
    t2 = time.time()
    print(t2-t1)

以下是我的問題:

  1. 如果我不使用以下asyncio api 直接運行 Threadpool,可能會出現什么潛在問題:

     loop = asyncio.get_event_loop() loop.run_in_executor(...)

我已經查看了文檔,對我運行了簡單的測試用例,這看起來非常好,它將使用自定義線程池在后台運行 IO 操作,如此所列,我當然不能使用純異步等待來接收 Output 和必須使用 map 或提交方法來管理呼叫,除此之外,我在這里沒有看到負面影響。

我的代碼https://ideone.com/lDVLFh的 Ideone 鏈接

如果我直接運行 Threadpool,可能會出現什么問題

如果您只是將東西提交到您的線程池並且從不與它交互或等待結果,那么沒有問題。 但是您的代碼確實在等待結果¹。

問題是ExecuteSleep正在阻塞 盡管它被定義為async def ,但它只是名稱上的異步,因為它不等待任何東西。 在它運行時,沒有其他 asyncio 協程可以運行,因此它破壞了 asyncio 的主要優點,即同時運行多個協程。


¹ 即使您刪除了對 `result()` 的調用,`with` 語句也會等待工人完成他們的工作,以便能夠終止他們。 如果您希望同步功能完全在后台運行,您可以將池設為全局而不使用 `with` 來管理它。

暫無
暫無

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

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