Featured image of post Python asyncio协程 - gather(4)

Python asyncio协程 - gather(4)

在Python 3的协程中,官方针对gather的使用有几个特性的说明,先说第五点的特性

如果 gather() 被取消,所有被提交 (尚未完成) 的可等待对象也会 被取消。

前面的几篇文章分别记录了gather的四个特性,为了下面的记录能够比较好的理解,请先回顾

下面先记录下一个简单的例子来说明问题

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18

import asyncio

async def fac(x, y):
    if x == 0:
        raise ZeroDivisionError
    else:
        await asyncio.sleep(5)
        print(f"{x} / {y} = {x/y}")
        return x / y

async def main():
    t = asyncio.gather(fac(0, 2), fac(1, 2), fac(3, 4))
    await asyncio.sleep(1)
    t.cancel()
    await t

asyncio.run(main())

运行后得到的结果如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ python main.py
1 / 2 = 0.5
3 / 4 = 0.75
Traceback (most recent call last):
  File "main.py", line 29, in <module>
    asyncio.run(main())
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
    return future.result()
  File "main.py", line 26, in main
    await t
  File "main.py", line 15, in fac
    raise ZeroDivisionError
ZeroDivisionError

似乎看不出什么效果

我们将gather的代码修改如下,将sleeo的时间增加到5秒

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import asyncio

async def fac(x, y):
    if x == 0:
        raise ZeroDivisionError
    else:
        await asyncio.sleep(5)
        print(f"{x} / {y} = {x/y}")
        return x / y

async def main():
    t = asyncio.gather(fac(0, 2), fac(1, 2), fac(3, 4))
    await asyncio.sleep(1)
    t.cancel()
    await t

asyncio.run(main())

运行后得到的结果如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ python main.py
Traceback (most recent call last):
  File "main.py", line 30, in <module>
    asyncio.run(main())
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
    return future.result()
  File "main.py", line 27, in main
    await t
  File "main.py", line 16, in fac
    raise ZeroDivisionError
ZeroDivisionError

从这里可以很清楚的了解这一特性

只要有一个是异常的后面的尚未执行的也会被取消

Licensed under CC BY-NC-SA 4.0
最后更新于 Jul 30, 2025 11:03 +0800