等待任何未来的asyncio

时间:2016-09-08 22:05:10

标签: python python-asyncio executor

我尝试使用asyncio来处理并发网络I / O.在一个点上安排了大量的功能,这些功能在每个功能完成所需的时间上变化很大。然后,对于每个输出,在单独的过程中处理接收的数据。

处理数据的顺序是不相关的,因此考虑到输出的等待时间可能非常长,我希望await对于任何将来完成而不是预定义的顺序。

def fetch(x):
    sleep()

async def main():
    futures = [loop.run_in_executor(None, fetch, x) for x in range(50)]
    for f in futures:
       await f

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

通常,等待期货排队的顺序很好:

Well behaved functions profiler graph

蓝色表示每个任务在执行程序队列中的时间,即run_in_executor已被调用,但该函数尚未执行,因为执行程序仅同时运行5个任务;绿色是执行功能本身所花费的时间;红色是等待所有先前期货到await所花费的时间。

Volatile functions profiler graph

在我的情况下,函数的时间变化很大,等待队列中的前一个等待时间会有很多时间丢失,而我可以在本地处理GET输出。这使得我的系统空闲一段时间只是在几个输出同时完成时被淹没,然后跳回空闲等待更多请求完成。

有没有办法await执行者首先完成的任何未来?

1 个答案:

答案 0 :(得分:7)

您似乎正在寻找return_when=asyncio.FIRST_COMPLETED的{​​{3}}。

def fetch(x):
    sleep()

async def main():
    futures = [loop.run_in_executor(None, fetch, x) for x in range(50)]
    while futures:
        done, futures = await asyncio.wait(futures, 
            loop=loop, return_when=asyncio.FIRST_COMPLETED)  
        for f in done:
            await f

loop = asyncio.get_event_loop()
loop.run_until_complete(main())