“等待未来”和“等待未来”之间是否存在差异?和#等待asyncio.wait_for(未来,无)'?

时间:2017-09-13 19:38:01

标签: python python-3.5 python-asyncio

使用python 3.5或更高版本,直接将await应用于未来或任务,并将其与asyncio.wait_for包装之间有什么区别吗?文档不清楚何时适合使用wait_for,并且我想知道它是否是旧的基于生成器的库的遗迹。 下面的测试程序出现以显示没有区别但是并没有真正证明什么。

import asyncio

async def task_one():
    await asyncio.sleep(0.1)
    return 1

async def task_two():
    await asyncio.sleep(0.1)
    return 2

async def test(loop):
    t1 = loop.create_task(task_one())
    t2 = loop.create_task(task_two())

    print(repr(await t1))
    print(repr(await asyncio.wait_for(t2, None)))

def main():
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(test(loop))
    finally:
        loop.close()

main()

2 个答案:

答案 0 :(得分:5)

wait_for提供了两个功能:

  1. 允许定义超时,
  2. 让您指定循环
  3. 你的例子:

    await f1
    await asyncio.wait_for(f1, None)  # or simply asyncio.wait_for(f1)
    

    除了调用额外包装器(wait_for)的开销之外,它们是相同的(https://github.com/python/cpython/blob/master/Lib/asyncio/tasks.py#L318)。

    两个awaits将无限期地等待结果(或异常)。在这种情况下,普通await更合适。

    另一方面,如果您提供超时参数,它将等待具有时间约束的结果。如果超过超时时间将超过TimeoutError,未来将被取消。

    async def my_func():
        await asyncio.sleep(10)
        return 'OK'
    
    # will wait 10s 
    await my_func()
    
    # will wait only 5 seconds and then will raise TimeoutError
    await asyncio.wait_for(my_func(), 5)
    

    另一件事是循环参数。在大多数情况下你不应该被打扰,用例是有限的:为测试注入不同的循环,运行其他循环......

    此参数的问题是,所有后续任务/函数也应该传递该循环...

    更多信息https://github.com/python/asyncio/issues/362

答案 1 :(得分:3)

不幸的是python文档在这里有点不清楚,但是如果你看一下sources它很明显:

await相反,协程asyncio.wait_for()允许在未来/任务完成之前等待有限的时间。如果在此时间内未完成,则会引发concurrent.futures.TimeoutError

此超时可以指定为第二个参数。在您的示例代码中,此timeout参数为None,这导致完全与直接应用await / yield from相同的功能。