为什么asyncio.wait_for()需要超时?

时间:2017-11-24 05:44:48

标签: python python-asyncio

下面是一个简单的asyncio循环,它运行两个后台任务。

他们都执行简单的计数。第一个永远计数,包裹在一个 尝试/除外。第二个计数最多为5,然后取消第一个和 停止循环。

有两种方法可以确保取消完成 -

asyncio.wait([a sequence of futures])

asyncio.wait_for(a single future)

两者都采取可选的超时。

如果我在没有超时的情况下使用第一种方法,则取消完成并且 循环停止。

如果我在没有超时的情况下使用第二种方法,则取消将来,但是 程序挂起。

如果我向第二个添加超时,它的行为与第一个相同。

这是否有原因?

我使用的是版本3.6.0。

import asyncio
from itertools import count

async def counter1():
    cnt = count(1)
    try:
        while True:
            print('From 1:', next(cnt))
            await asyncio.sleep(1)
    except asyncio.CancelledError:
        print('counter1 cancelled')

async def counter2():
    cnt = count(1)
    for i in range(5):
        print('From 2:', next(cnt))
        await asyncio.sleep(1)
    cnt1.cancel()
#   await asyncio.wait([cnt1])  # works
#   await asyncio.wait_for(cnt1)  # hangs
    await asyncio.wait_for(cnt1, 1)  # works
    loop.stop()

loop = asyncio.get_event_loop()
cnt1 = asyncio.ensure_future(counter1())
cnt2 = asyncio.ensure_future(counter2())
loop.run_forever()

1 个答案:

答案 0 :(得分:1)

我在comp.lang.python上收到了以下答案 -

“当循环退出时,未处理的异常显示为警告。在此之前无法显示它,因为可能还有其他任务,即使尚未安排的任务,也可能尝试获取counter2任务的结果并处理异常。“

我在Windows上测试。我从来没有让Ctrl-C在Windows上运行,因此我使用Ctrl-Pause,它会在没有显示任何挂起的回溯的情况下崩溃解释器。

在Linux上运行程序并按Ctrl-C会显示回溯。如果我首先在Linux上进行测试,则无需发布原始问题。