【发布时间】:2015-06-10 19:30:45
【问题描述】:
我有一个事件循环,它作为命令行工具的一部分运行一些协同例程。用户可以使用通常的 Ctrl + C 中断工具,此时我想在中断的事件循环之后正确清理。
这是我尝试过的。
import asyncio
@asyncio.coroutine
def shleepy_time(seconds):
print("Shleeping for {s} seconds...".format(s=seconds))
yield from asyncio.sleep(seconds)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
# Side note: Apparently, async() will be deprecated in 3.4.4.
# See: https://docs.python.org/3.4/library/asyncio-task.html#asyncio.async
tasks = [
asyncio.async(shleepy_time(seconds=5)),
asyncio.async(shleepy_time(seconds=10))
]
try:
loop.run_until_complete(asyncio.gather(*tasks))
except KeyboardInterrupt as e:
print("Caught keyboard interrupt. Canceling tasks...")
# This doesn't seem to be the correct solution.
for t in tasks:
t.cancel()
finally:
loop.close()
运行这个并点击 Ctrl + C 产生:
$ python3 asyncio-keyboardinterrupt-example.py
Shleeping for 5 seconds...
Shleeping for 10 seconds...
^CCaught keyboard interrupt. Canceling tasks...
Task was destroyed but it is pending!
task: <Task pending coro=<shleepy_time() running at asyncio-keyboardinterrupt-example.py:7> wait_for=<Future cancelled> cb=[gather.<locals>._done_callback(1)() at /usr/local/Cellar/python3/3.4.3/Frameworks/Python.framework/Versions/3.4/lib/python3.4/asyncio/tasks.py:587]>
Task was destroyed but it is pending!
task: <Task pending coro=<shleepy_time() running at asyncio-keyboardinterrupt-example.py:7> wait_for=<Future cancelled> cb=[gather.<locals>._done_callback(0)() at /usr/local/Cellar/python3/3.4.3/Frameworks/Python.framework/Versions/3.4/lib/python3.4/asyncio/tasks.py:587]>
显然,我没有正确清理。我想也许在任务上调用cancel() 是一种方法。
事件循环中断后清理的正确方法是什么?
【问题讨论】:
-
以防万一,我在 OS X 10.10.3 上运行 Python 3.4.3。
标签: python python-3.4 python-asyncio