import asyncio
async def io_bound_task(semaphore, task_number):
async with semaphore:
print(f"Task {task_number} is starting I/O operation.")
await asyncio.sleep(1) # 模拟I/O操作,如网络请求或文件读取
print(f"Task {task_number} has finished I/O operation.")
async def main():
semaphore = asyncio.Semaphore(5) # 创建一个信号量,最多允许5个任务同时运行
tasks = [io_bound_task(semaphore, i) for i in range(10)] # 创建10个任务
await asyncio.gather(*tasks) # 等待所有任务完成
if __name__ == "__main__":
asyncio.run(main())
代码解释
- 定义
io_bound_task
函数:
semaphore
:传入的信号量对象,用于控制并发。
task_number
:任务编号,用于标识不同任务。
async with semaphore
:使用 async with
语句获取信号量。如果当前已有5个任务持有信号量(因为信号量初始值为5),则新任务会在此处等待,直到有任务释放信号量。一旦获取到信号量,任务可以继续执行。
await asyncio.sleep(1)
:模拟I/O操作,如网络请求或文件读取,使当前任务暂停1秒。
print
语句:在任务开始和结束I/O操作时打印信息,方便观察任务执行情况。
- 定义
main
函数:
semaphore = asyncio.Semaphore(5)
:创建一个 Semaphore
对象,其初始值为5,表示最多允许5个任务同时运行。
tasks = [io_bound_task(semaphore, i) for i in range(10)]
:使用列表推导式创建10个 io_bound_task
任务。
await asyncio.gather(*tasks)
:等待所有任务完成。asyncio.gather
会并发运行传入的所有任务,而信号量则控制同时运行的任务数量。
if __name__ == "__main__"
部分:
asyncio.run(main())
:在Python 3.7+ 中,这是运行异步程序的标准方式,启动 main
函数的执行。通过这种方式,使用 Semaphore
来有效控制包含大量I/O操作的异步程序的并发数量,避免资源耗尽并提升整体性能。