一 协程的定义与Python 的实现
1.1 协程是什么
协程 是一种轻量级的并发单元,它允许在等待异步操作(如 I/O 操作)时挂起,从而让出控制权给事件循环,以便执行其他任务。简单来说可以认为协程是线程里不同的函数,这些函数之间可以相互快速切换。协程的主要特点包括:
非阻塞:协程在等待异步操作时不会阻塞事件循环,从而实现非阻塞的并发执行。 协作式多任务:协程通过 await 表达式主动让出控制权,实现协作式多任务处理。 易于编写:使用 async/await 语法,协程的编写和理解都相对简单直观。
在 Python 中,asyncio
是一个用于编写并发代码的库,它使用 async
/await
语法。async
定义了一个协程,而 await
用于等待异步操作完成。协程是一种轻量级的线程,它允许在等待异步操作完成时挂起,从而让出控制权给其他协程。
asyncio 函数的源代码地址:https://github.com/python/cpython/tree/3.8/Lib/asyncio
1.2 特点
非阻塞:协程是非阻塞的,它们在等待异步操作时不会阻塞整个程序的执行。 轻量级:相比传统的线程,协程不需要操作系统级别的上下文切换,其开销更小。 易于编写: asyncio
使用 async/await 语法,协程的编写和理解都相对简单直观。单线程:尽管协程可以并发执行,但它们通常在单个线程内运行,由事件循环来调度。
1.3 适用场景
I/O 密集型任务:如网络请求、文件读写等,这些操作通常需要等待外部资源,协程可以在等待时释放控制权。 高并发:需要同时处理大量并发连接或任务,但每个任务的执行时间较短。 异步 API:与异步 API 交互,如异步数据库访问、异步 HTTP 客户端等。
1.4 限制
需要编译器提供语义支持,比如C# yield return语法糖。
只能在这个生成器内挂起此协程,无法在嵌套函数中挂起此协程。
关键字有一定传染性,异步代码必须都有对应的关键字。
二 asyncio 协程相关函数的使用
创建协程
使用 async def
定义一个协程函数:
async def my_coroutine():
print("Hello")
await asyncio.sleep(1)
print("World")
运行协程
使用 asyncio.run()
来运行协程:
asyncio.run(my_coroutine())
等待协程
使用 await
等待协程完成:
async def main():
print("Start")
await my_coroutine()
print("Finished")
asyncio.run(main())
并发运行多个协程
使用 asyncio.gather()
并发运行多个协程:
async def coroutine1():
print("Coroutine 1 started")
await asyncio.sleep(2)
print("Coroutine 1 finished")
async def coroutine2():
print("Coroutine 2 started")
await asyncio.sleep(1)
print("Coroutine 2 finished")
async def main():
await asyncio.gather(coroutine1(), coroutine2())
asyncio.run(main())
三 使用场景代码示例
3.1 网络请求
使用 aiohttp
库进行异步 HTTP 请求:
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
html = await fetch(session, 'http://python.org')
print(html)
asyncio.run(main())
3.2 模拟处理请求
假设我们模拟一个简单的Web服务器,该服务器能够同时处理多个客户端的HTTP GET请求,每个请求需要从数据库或其他服务获取数据,这是一个典型的I/O密集型任务。
import asyncio
async def handle_client(client_id, delay):
print(f"客户端{client_id} 连接,开始处理请求...")
await asyncio.sleep(delay) # 模拟数据处理或I/O操作
print(f"客户端{client_id} 请求处理完毕")
async def main():
clients = [handle_client(i, i % 3 + 1) for i in range(1, 6)] # 创建不同延时的客户端请求
await asyncio.gather(*clients) # 同时处理所有客户端请求
asyncio.run(main())
四 小结
asyncIO 及其协程模型为 Python 开发者提供一种高效处理并发I/O操作的方法。通过合理的运用 async/await 语法、事件循环以及任务管理,开发者便能够轻松构建高性能的异步应用程序。
文章转载自yangyidba,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




