【发布时间】:2017-03-15 01:31:08
【问题描述】:
我正在使用 Python asyncio。我的程序只有三个协程。其中两个是我直接安排的,而第三个是从前者之一安排的。当用户按下Ctrl+C时,我想正确地完成我的程序:
import asyncio
async def coro1():
try:
print('coro1')
await asyncio.sleep(1000)
except Exception as e:
print('coro1 exc %s' % repr(e))
raise
async def coro2():
try:
print('coro2')
await asyncio.ensure_future(coro3())
await asyncio.sleep(1000)
except Exception as e:
print('coro2 exc %s' % repr(e))
raise
async def coro3():
try:
print('coro3')
await asyncio.sleep(1000)
except Exception as e:
print('coro3 exc %s' % repr(e))
raise
loop = asyncio.get_event_loop()
try:
f1 = asyncio.ensure_future(coro1())
f2 = asyncio.ensure_future(coro2())
loop.run_forever()
except KeyboardInterrupt:
print('Exiting... Cancelling all tasks')
f2.cancel()
f1.cancel()
# This code gives the same result:
# for task in asyncio.tasks.Task.all_tasks(loop):
# task.cancel()
print('Cancellation is done!')
loop.stop()
loop.run_forever()
finally:
loop.close()
这段代码产生下一个输出:
coro1
coro2
coro3
^CExiting... Cancelling all tasks
Cancellation is done!
coro3 exc CancelledError()
coro1 exc CancelledError()
Task was destroyed but it is pending!
task: <Task pending coro=<coro2() running at test.py:15> wait_for=<Task cancelled coro=<coro3() done, defined at test.py:23>>>
所以我想知道,为什么coro2 没有被取消而coro3 实际上被 取消了?
【问题讨论】:
-
协程 3 返回后协程 2 再休眠 1000 秒。尝试更短的睡眠时间(或等待 1000 秒!)
-
@shongololo,恐怕即使我完全删除
await sleep(1000),观察到的行为也不会改变。 -
啊,我没有看到您的代码示例的最低行(被滚动隐藏)。可能是协程 2 在循环关闭时没有机会返回异常并关闭。您可以在关闭循环之前等待检查所有任务是否已取消,但是您将看不到正在运行的异常...
-
@shongololo 看起来我找到了答案。
标签: python python-asyncio coroutine event-loop