可等待对象
如果一个对象可以在 await 语句中使用,那么它就是 可等待 对象。许多 asyncio API 都被设计为接受可等待对象。
可等待 对象有三种主要类型: 协程, 任务 和 Future.
协程
协程 属于 可等待 对象,通过 async/await 语法进行声明,是编写 asyncio 应用的推荐方式。
协程函数
: 定义形式为 async def 的函数;协程对象
: 调用 协程函数
所返回的对象。
注意:简单地调用一个协程函数
并不会立即执行,只是返回一个协程对象
。
使用 asyncio.run() 函数来调用协程对象
,协程函数
才会被真正执行。
示例1:
>>> import asyncio
>>> async def main():
... print('hello')
... await asyncio.sleep(1)
... print('world')
>>> main()
<coroutine object main at 0x1053bb7c8>
>>> asyncio.run(main())
hello
world
示例2:
import asyncio
async def nested():
return 42
async def main():
# 此处仅仅创建了一个协程对象,nested函数并没有真正执行。
# 必须使用 await 关键字,后面可用asyncio.run()函数调用执行。
nested()
# 使用 await 关键字
print(await nested()) # will print "42".
main())
任务
任务
被用来设置日程以便 并发
执行协程。【个人理解:协程无法直接并发执行,必须打包成任务】
创建任务
asyncio.create_task(coro, *, name=None)
将 协程对象
coro 打包为一个 Task
任务,排入日程准备执行。 返回 Task 对象
。
name 不为 None,它将使用 Task.set_name()
来设为任务的名称。
该任务会在 get_running_loop() 返回的循环中执行,如果当前线程没有在运行的循环则会引发 RuntimeError。
休眠
coroutine asyncio.sleep(delay, result=None, *, loop=None)
并发运行任务
awaitable asyncio.gather(*aws, loop=None, return_exceptions=False)
并发 运行 aws 序列中的 可等待对象.
如果 aws 中的某个可等待对象为协程
,它将自动作为一个任务(自动创建Task对象
)加入日程。
如果所有可等待对象都成功完成,结果将返回一个由所有返回值聚合而成的列表。
示例代码:
import asyncio
import time
# 并发执行协程
# 模拟的耗时任务 交给协程来处理
async def my_task(name, number):
await asyncio.sleep(number)
print('%s 已经完成任务...' % name)
return number
async def main():
print(f"started at {time.strftime('%X')}")
# 将三个任务交给 asyncio.gather 并发执行。预期耗时4秒,否则未达到预期
main_res = await asyncio.gather(
my_task('A', 2),
my_task('B', 3),
my_task('C', 4),
)
# 压缩参数为列表变量的形式
# task_list = [my_task('A', 2), my_task('B', 2), my_task('C', 4)]
# main_res = await asyncio.gather(*task_list)
# 以下方法为并发异步执行,可达相同预期。 但在协程较多时,推荐使用上法
# task1 = asyncio.create_task(my_task('A', 2))
# task2 = asyncio.create_task(my_task('B', 3))
# task3 = asyncio.create_task(my_task('C', 4))
# await task1
# await task2
# await task3
# 返回一个由所有返回值聚合而成的列表
print(main_res)
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
结果如下:
started at 14:46:26
A 已经完成任务...
B 已经完成任务...
C 已经完成任务...
[2, 3, 4]
finished at 14:46:30
async def my_task(name, number)
为需要并发执行的异步方法
.- 通过
await asyncio.gather()
,对多个并发执行的函数方法,进行调用。 - 将
await asyncio.gather()
放入async def main()
方法函数中使用。 - 使用
asyncio.run(main())
调用async def main()
方法
asyncio 异步 I/O https://docs.python.org/zh-cn/3.9/library/asyncio.html
简单粗暴有效上手Python3异步asyncio https://blog.csdn.net/lpwmm/article/details/102985040
Python3.7 高级编程之 async/await asyncio 通过任务gather并发运行协程 https://blog.csdn.net/haeasringnar/article/details/100181731