Python笔记之异步编程
一、简介
本章节详细讲解Python中的异步编程,涵盖异步I/O、协程(asyncio
模块)以及异步任务与事件循环的相关概念。异步编程是一种处理I/O密集型任务的有效方式,可以显著提高程序的并发能力,尤其是在处理大量I/O操作时。Python的asyncio
模块为我们提供了对异步编程的支持,使得编写异步代码变得更加简洁。
二、异步I/O与协程(asyncio
模块)
1、概念说明
-
异步I/O:传统的同步I/O操作在等待数据的过程中会阻塞程序的执行,而异步I/O可以在等待数据的过程中不阻塞程序,允许其他任务执行。当数据准备好时,异步操作会继续执行。这种方式适用于I/O密集型任务。
-
协程:协程是一种轻量级的线程,能够在执行过程中主动挂起和恢复。Python的协程通过
async
和await
关键字来实现,async
用于定义协程,await
用于挂起协程,等待异步操作完成。
2、代码示例
(1) 定义协程函数
import asyncio
# 定义协程函数
async def my_coroutine():
print("协程开始")
await asyncio.sleep(2) # 模拟异步I/O操作
print("协程结束")
# 运行协程
asyncio.run(my_coroutine())
运行结果
协程开始
(等待2秒)
协程结束
(2) 多个协程并发执行
import asyncio
# 定义协程函数
async def task(name, delay):
print(f"{name}开始")
await asyncio.sleep(delay)
print(f"{name}结束")
# 创建多个协程并发执行
async def main():
await asyncio.gather(
task("任务1", 2),
task("任务2", 1),
task("任务3", 3)
)
# 运行异步任务
asyncio.run(main())
运行结果
任务1开始
任务2开始
任务3开始
任务2结束
任务1结束
任务3结束
三、异步任务与事件循环
1、概念说明
-
异步任务:异步任务是由
asyncio
模块的事件循环调度并执行的协程。在Python中,通过asyncio.create_task()
可以创建任务,它将一个协程包装成一个任务对象,并且会被事件循环调度。 -
事件循环:事件循环是异步编程的核心,负责调度和执行异步任务。通过
asyncio.run()
可以运行事件循环并执行主协程。事件循环会管理任务的执行,并确保每个任务在等待期间不会阻塞其他任务。
2、代码示例
(1) 使用asyncio.create_task()
创建异步任务
import asyncio
# 定义协程函数
async def task(name, delay):
print(f"{name}开始")
await asyncio.sleep(delay)
print(f"{name}结束")
# 创建任务并运行事件循环
async def main():
task1 = asyncio.create_task(task("任务1", 2))
task2 = asyncio.create_task(task("任务2", 1))
task3 = asyncio.create_task(task("任务3", 3))
# 等待任务完成
await task1
await task2
await task3
# 运行异步任务
asyncio.run(main())
运行结果
任务1开始
任务2开始
任务3开始
任务2结束
任务1结束
任务3结束
(2) 使用asyncio.gather()
并行执行多个任务
import asyncio
# 定义协程函数
async def task(name, delay):
print(f"{name}开始")
await asyncio.sleep(delay)
print(f"{name}结束")
# 创建多个协程任务并并行执行
async def main():
await asyncio.gather(
task("任务1", 2),
task("任务2", 1),
task("任务3", 3)
)
# 运行异步任务
asyncio.run(main())
运行结果
任务1开始
任务2开始
任务3开始
任务2结束
任务1结束
任务3结束
四、异步编程的优势与应用场景
1、概念说明
-
异步编程的优势:异步编程能在程序等待I/O操作时不阻塞其他任务的执行,从而提升程序的并发性能。对于I/O密集型任务(如网络请求、文件操作等),使用异步编程能显著提高效率。
-
应用场景:异步编程特别适合处理大量并发的I/O操作,例如Web服务器、爬虫、数据库操作等。Python的
asyncio
模块广泛应用于这些场景中。
2、代码示例
(1) 异步爬虫模拟
import asyncio
import random
# 定义异步下载页面函数
async def download_page(url):
print(f"开始下载 {url}")
await asyncio.sleep(random.randint(1, 3)) # 模拟下载时间
print(f"下载完成 {url}")
# 异步下载多个页面
async def main():
urls = ["page1.html", "page2.html", "page3.html"]
await asyncio.gather(*(download_page(url) for url in urls))
# 运行异步任务
asyncio.run(main())
运行结果
开始下载 page1.html
开始下载 page2.html
开始下载 page3.html
下载完成 page1.html
下载完成 page3.html
下载完成 page2.html
五、小结
本章节详细讲解了Python中的异步编程,介绍了异步I/O、协程(asyncio
模块)、异步任务与事件循环的概念和使用方法。通过协程与asyncio
模块,Python可以高效地处理I/O密集型任务,并充分利用并发性能。异步编程特别适合Web爬虫、网络请求等应用场景。掌握这些概念后,我们能够编写更加高效、并发性更强的程序。