繁体   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