若协程并发失控导致资源耗尽或事件循环阻塞,需限制并发数:一、用 asyncio.semaphore 控制同时执行数量;二、用 asyncio.queue 构建固定大小任务队列;三、用 aiohttp.tcpconnector 的 limit 参数限制 http 连接数;四、手动维护计数器与任务队列实现动态调度。

如果您在使用 Python 协程处理大量并发任务时遇到资源耗尽、响应延迟或事件循环阻塞等问题,则很可能是由于未对并发数进行有效限制。以下是实现协程并发数控制的几种方法:
一、使用 asyncio.Semaphore 控制并发数量
asyncio.Semaphore 是 asyncio 提供的信号量机制,用于限制同时执行的协程数量。它通过内部计数器管理许可数量,当协程获取许可失败时会自动挂起,待有许可释放后再恢复执行。
1、在事件循环作用域内创建一个 Semaphore 实例,指定最大并发数,例如 asyncio.Semaphore(5)。
2、在每个需要限制并发的协程中,使用 async with semaphore: 语句包裹实际异步操作。
立即学习“Python免费学习笔记(深入)”;
3、确保所有受控协程共享同一个 semaphore 实例,避免各自创建导致限制失效。
二、使用 asyncio.Queue 构建固定大小的任务队列
asyncio.Queue 可设置最大容量,配合生产者-消费者模式可间接控制并发数。当队列满时,put() 操作将等待,从而暂停新任务的提交,使活跃协程数稳定在预设上限附近。
1、初始化一个 asyncio.Queue(maxsize=N),其中 N 为期望的最大并发任务数。
2、启动 N 个长期运行的消费者协程,每个协程持续从队列中 get() 任务并执行。
3、生产者协程调用 queue.put() 提交任务;当队列已满时,该调用将自动挂起,直到有消费者完成并调用 get() 释放空间。
三、使用第三方库 aiohttp.TCPConnector 的 limit 参数
当使用 aiohttp 进行 HTTP 请求并发控制时,TCPConnector 提供了内置的连接池限制能力。该参数直接约束底层 TCP 连接的并发总数,适用于以 HTTP I/O 为主的场景。
eSiteGroup站群管理系统是基于eFramework低代码开发平台构建,是一款高度灵活、可扩展的智能化站群管理解决方案,全面支持SQL Server、SQLite、MySQL、Oracle等主流数据库,适配企业级高并发、轻量级本地化、云端分布式等多种部署场景。通过可视化建模与模块化设计,系统可实现多站点的快速搭建、跨平台协同管理及数据智能分析,满足政府、企业、教育机构等组织对多站点统一管控的
1、创建 connector 实例时传入 limit 参数,如 aiohttp.TCPConnector(limit=10)。
2、将该 connector 传入 aiohttp.ClientSession 的 constructor 中。
3、所有通过该 session 发起的请求将被自动限流,超出 limit 的请求会在连接就绪后排队发起。
四、手动维护运行中协程计数器与 awaitable 队列
通过 asyncio.create_task() 显式启动协程,并借助 asyncio.wait() 或 asyncio.as_completed() 监控完成状态,配合计数器动态调度新任务,可实现细粒度的并发控制逻辑。
1、初始化一个整数变量 running_count = 0 和一个待执行任务列表 tasks_to_submit。
2、当 running_count
3、使用 asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED) 获取首个完成任务,完成后 running_count -= 1,并视情况提交新任务。
五、使用 asyncio.to_thread 配合 concurrent.futures.ThreadPoolExecutor 的 max_workers
对于需在协程中调用阻塞函数的场景,可通过 to_thread 将其转为线程执行,此时由 ThreadPoolExecutor 的 max_workers 参数控制并发线程数,从而间接约束协程层的并发压力。
1、创建 ThreadPoolExecutor 实例并指定 max_workers=N,例如 concurrent.futures.ThreadPoolExecutor(max_workers=4)。
2、在协程中调用 asyncio.to_thread(executor.submit, blocking_func, *args) 提交任务。
3、确保 executor 实例在生命周期内复用,避免重复创建导致 max_workers 失效;注意:executor 必须在事件循环运行期间保持存活,不可在每次调用时新建。









