Python asyncio Semaphore

Python 中的 asyncio 模块提供了异步编程的支持,其中 Semaphore(信号量)是一种用于限制并发任务数量的同步原语。

信号量通过维护一个内部计数器来控制对共享资源的访问,只有当计数器大于零时,任务才能获取信号量并执行相关操作。

获取信号量后,内部计数器会减一,释放信号量时则加一,从而确保同时只有固定数量的任务在运行。这种机制对于限制对某些资源(如网络请求、文件操作等)的并发访问具有重要意义。


使用示例

下面提供一个使用 asyncio.Semaphore 的示例,该示例通过信号量限制同时运行的协程数量,从而控制并发任务的数量

示例中定义了一个异步任务,该任务在获取信号量后模拟执行耗时操作,最后释放信号量。

import asyncio
import random

async def worker(semaphore, worker_id):
    # 尝试获取信号量
    async with semaphore:
        print(f"Worker {worker_id} 开始工作")
        # 模拟耗时操作
        await asyncio.sleep(random.uniform(0.5, 2.0))
        print(f"Worker {worker_id} 工作完成")

async def main():
    # 限制同时只有3个任务可以运行
    semaphore = asyncio.Semaphore(3)
    tasks = []
    for i in range(10):
        task = asyncio.create_task(worker(semaphore, i))
        tasks.append(task)
    # 等待所有任务完成
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())

该示例中首先创建了一个 Semaphore 实例,并将并发任务数限制为 3。接着创建 10 个 worker 协程,每个协程在执行任务前都必须获取信号量。由于信号量的限制,只有 3 个 worker 能够同时运行,其余 worker 会等待信号量释放。通过这种方式,可以有效控制同时运行的任务数量,防止资源过载。


注意事项

在使用 asyncio.Semaphore 时需要注意以下几个方面。首先,信号量主要用于限制并发访问,如果没有实际的资源限制需求,滥用可能会降低程序的并发效率。其次,确保在获取信号量的代码块内正确处理异常,避免因异常导致信号量未释放,从而造成死锁或资源长期占用。最后,建议使用 async with 语法管理信号量的获取和释放,以确保代码的简洁性和正确性。


本文作者:Maeiee

本文链接:Python asyncio Semaphore

版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!


喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!