第四十五章:asyncio 异步 I/O
一、简介
官网:https://docs.python.org/zh-cn/3.13/library/asyncio.html
asyncio 是用来编写 并发 代码的库,使用 async/await 语法。
asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。
asyncio 往往是构建 IO 密集型和高层级 结构化 网络代码的最佳选择。
# Hello World!
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
asyncio.run(main())
二、常用方法
# async
定义异步函数的关键字,主要用于处理异步编程
# await
声明 可等待 对象,await 必须在 async 函数中使用。
# 1.asyncio.run()
用来运行最高层级的入口点 "main()" 函数
此函数会运行传入的协程,负责管理 asyncio 事件循环、终结异步生成器、并关闭执行器。
# 2.asyncio.create_task(coro, *, name=None, context=None)
将 coro 协程 封装为一个 Task 并调度其执行。返回 Task 对象
函数用来并发运行作为 asyncio 任务 的多个协程。
# 3.TaskGroup()
任务组
# 4.asyncio.sleep(delay, result=None)
阻塞 delay 指定的秒数。如果指定了 result,则当协程完成时将其返回给调用者。
sleep() 总是会挂起当前任务,以允许其他任务运行。
# 5.asyncio.gather(*aws, return_exceptions=False)¶
并发运行任务
# 6.asyncio.timeout(delay)
返回一个可被用于限制等待某个操作所耗费时间的 异步上下文管理器
async def main():
async with asyncio.timeout(10):
await long_running_task()
三、信号量
Semaphore 可以限制同时运行的协程数量。
在这个例子中,Semaphore(10) 表示最多可以有 10 个协程同时访问某个共享资源或执行某个操作。
帮助管理并发,以提高程序的稳定性和资源的有效利用。
# class asyncio.Semaphore(value=10)
信号量对象
sem = asyncio.Semaphore(10)
# ... 稍后
async with sem:
# 操作共享的资源
import asyncio
async def limited_task(sem, task_id):
async with sem: # 获取信号量
print(f"Task {task_id} 正在执行")
await asyncio.sleep(2) # 模拟异步操作
print(f"Task {task_id} 完成")
async def main():
sem = asyncio.Semaphore(10) # 创建信号量,限制并发数为 10
tasks = [limited_task(sem, i) for i in range(20)] # 创建 20 个任务
await asyncio.gather(*tasks) # 并发执行
# 运行主函数
asyncio.run(main())
四、异常
# asyncio.TimeoutError
会在操作超出了给定的时限时引发
# asyncio.CancelledError
该操作已被取消
# asyncio.InvalidStateError
Task 或 Future 的内部状态无效。
在为已设置结果值的未来对象设置结果值等情况下,可以引发此问题。
# exception asyncio.SendfileNotAvailableError
"sendfile" 系统调用不适用于给定的套接字或文件类型。
# asyncio.IncompleteReadError
请求的读取操作未完全完成。
# asyncio.LimitOverrunError
在查找分隔符时达到缓冲区大小限制。
五、示例
# 进程中开协程:见run.py
getee:https://gitee.com/ysging/mqtt_django.git

浙公网安备 33010602011771号