1、协程是一种轻量级的并发机制,允许你在单个线程内模拟并发执行多个任务。协程非常适合用于 I/O 密集型任务,如网络请求、文件读写等,在等待 I/O 操作完成时,协程可以继续执行其他任务而不是阻塞。
生成器:
yield
表达式暂停其执行,并在后续调用 next()
方法时恢复执行。yield
表达式返回一个值,并保存当前的状态,以便下次调用时可以从上次暂停的地方继续执行。异步编程:
asyncio
模块,提供了协程和异步编程的支持。关键字 async
和 await
:
async def
用于定义一个协程函数。await
用于在协程函数内部等待另一个协程的完成。 import asyncio
# 定义一个协程函数
async def task(name, delay):
print(f"{name} task starts.")
await asyncio.sleep(delay) # 模拟一个异步操作
print(f"{name} task finishes.")
async def main():
# 创建并启动两个任务
task1 = asyncio.create_task(task("Task 1", 2))
task2 = asyncio.create_task(task("Task 2", 1))
# 等待所有任务完成
# await task1
# await task2
await asyncio.gather(task1, task2)
# 运行协程
asyncio.run(main())
2、gevent
是一个 Python 库,它提供了一种轻量级的并发机制,使用 greenlets(绿色线程)来实现协程
轻量级:
gevent
的 greenlets 是轻量级的,可以在单个线程内运行多个 greenlets。非抢占性调度:
switch
方法时主动让出控制权。共享内存:
适合 I/O 密集型任务:
gevent
非常适合处理 I/O 密集型任务,如网络请求、文件读写等。在等待 I/O 操作完成时,greenlet 可以继续执行其他任务。异步编程:
gevent
提供了一种自然的方式来编写异步代码,使得代码更容易理解和维护。自动猴子补丁:
gevent
提供了一个“猴子补丁”(monkey patching)功能,可以将 Python 的标准库中的阻塞调用替换为非阻塞的版本。from gevent import monkey; monkey.patch_all() # 必须在导入其他库之前执行
import gevent
import requests
def fetch_url(url):
print(f"Fetching {url}...")
response = requests.get(url)
print(f"Fetched {url}: {len(response.text)} bytes")
def main():
urls = [
"https://www.example.com",
"https://www.example.org",
"https://www.example.net"
]
greenlets = [gevent.spawn(fetch_url, url) for url in urls]
gevent.joinall(greenlets)
if __name__ == "__main__":
start_time = time.time()
main()
end_time = time.time()
print(f"Total time taken: {end_time - start_time:.2f} seconds")
Monkey Patching:
monkey.patch_all()
用于自动将标准库中的阻塞调用替换为 gevent 的非阻塞版本。这是为了让 gevent 能够接管标准库中的网络请求等 I/O 操作。定义 greenlet 函数:
fetch_url
函数接受一个 URL 参数,并使用 requests.get()
发送网络请求。创建并启动 greenlets:
gevent.spawn()
来创建并启动 greenlets。gevent.joinall()
用于等待所有 greenlets 完成。性能测量:
time.time()
来记录开始和结束时间,计算总的执行时间。实现方式:
gevent
库提供支持,使用 gevent.greenlet.Greenlet
类。async/await
关键字。调度方式:
asyncio
)控制的。异步支持:
asyncio
一起使用,提供了一套完整的异步编程模型