【问题标题】:await for any future asyncio等待任何未来的异步
【发布时间】:2016-09-08 22:05:10
【问题描述】:

我正在尝试使用 asyncio 来处理并发网络 I/O。大量的功能将被安排在一个单一的点上,这些功能在每个完成时所花费的时间差异很大。接收到的数据随后会在每个输出的单独进程中进行处理。

处理数据的顺序无关紧要,因此考虑到输出等待时间可能很长,我想awaitawait,无论未来先完成,而不是预定义的顺序。

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())

通常,按照期货排队的顺序等待是可以的:

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

在我的情况下,函数的时间变化很大,在等待队列中的先前期货等待时会浪费很多时间,而我可以在本地处理 GET 输出。这使我的系统空闲了一段时间,只是在多个输出同时完成时变得不堪重负,然后跳回到空闲状态等待更多请求完成。

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

【问题讨论】:

  • 你用什么来可视化协程的执行? :)
  • @PovilasB 大量日志记录 time.time() 和 PIL
  • 如果您使用期货,我发现 as_completed 在事件结束时处理它们非常有帮助。

标签: python python-3.x python-asyncio executor


【解决方案1】:

看起来您正在寻找 asyncio.waitreturn_when=asyncio.FIRST_COMPLETED

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())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-18
    • 2014-09-06
    • 1970-01-01
    • 2013-02-10
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多