Python协程取消与错误处理

Python协程取消与错误处理

Python协程取消与错误处理 #

如果我们想给某些协程任务限定运行时间,一旦超时就取消,又该怎么做呢?再进一步,如果某些协程运行时出现错误,又该怎么处理呢?

import asyncio
async def worker_1():
    await asyncio.sleep(1)
    return 1
async def worker_2():
    await asyncio.sleep(2)
    return 2 / 0
async def worker_3():
    await asyncio.sleep(3)
    return 3
async def main():
    task_1 = asyncio.create_task(worker_1())
    task_2 = asyncio.create_task(worker_2())
    task_3 = asyncio.create_task(worker_3())
    await asyncio.sleep(2)
    task_3.cancel()
    res = await asyncio.gather(task_1, task_2, task_3, return_exceptions=True)
    print(res)
%time asyncio.run(main())
########## 输出 ##########
[1, ZeroDivisionError('division by zero'), CancelledError()]
Wall time: 2 s

你可以看到,worker_1 正常运行,worker_2 运行中出现错误,worker_3 执行时间过长被我们 cancel 掉了,这些信息会全部体现在最终的返回结果 res 中。

不过要注意return_exceptions=True这行代码。如果不设置这个参数,错误就会完整地 throw 到我们这个执行层,从而需要 try except 来捕捉,这也就意味着其他还没被执行的任务会被全部取消掉。为了避免这个局面,我们将 return_exceptions 设置为 True 即可。

Viewpoint #

封装成task后,任务的取消及异常处理才有可能。

From #

20 | 揭秘 Python 协程