Python使用asyncio与队列实现IP探测流水线运行卡顿求助
IP探测流水线ping执行完成后卡住问题排查
核心故障原因(按优先级排序)
- 作用域错误:B函数内没有声明
global providerTask, pingsTasks, SNMPTasks,赋值的是局部变量,全局的任务变量始终为None,ping、SNMP、watcher协程访问全局变量调用.done()时直接抛出异常,被asyncio.gather的return_exceptions=True吞掉,所有协程直接挂起无输出。 - asyncio.Queue方法未加await:ping函数中
ipListSNMP.put(ip)没有加await,协程未执行,IP不会被放入SNMP队列,所有SNMP协程永久卡在await ipListSNMP.get(),无后续动作。 - 循环条件逻辑错误:
- ping函数的循环条件
while not providerTask.done() or not ipListPing.join()中,ipListPing.join()是协程,直接做布尔判断永远返回True,循环永远不会退出。 - SNMP函数的循环条件误判断
ipListPing.join()的状态,和SNMP队列本身的处理进度完全无关,无法正确退出循环。
- ping函数的循环条件
- watcher终止逻辑永远不触发:判断条件写为
ipListPing.empty() is None,empty()方法返回布尔值,永远不可能等于None,ping和SNMP任务永远不会被cancel,程序无法正常收尾。 - 代码重复定义:重复粘贴了provider、ping、SNMP、SSH四个函数的定义,运行时会覆盖原有逻辑,可能引发不可预期的异常。
修复方案
- 在B函数开头添加全局变量声明:
def B(): global providerTask, pingsTasks, SNMPTasks # 原有逻辑
- 修正ping函数中的队列调用:
await aioping.ping(ip) # 加await await ipListSNMP.put(ip)
- 修正ping函数循环条件:
# 正确判断provider是否完成+ping队列是否为空 while not (providerTask.done() and ipListPing.empty()): # 原有逻辑
- 修正SNMP函数循环条件:
# 正确判断ping任务是否完成+SNMP队列是否为空 while not (pingsTasks.done() and ipListSNMP.empty()): # 原有逻辑
- 修正watcher的判断逻辑:
if providerTask.done() and ipListPing.empty(): logging.debug("终止PING任务") pingsTasks.cancel() await ipListSNMP.join() if pingsTasks.done() and ipListSNMP.empty(): logging.debug("终止SNMP任务") SNMPTasks.cancel()
- 删除重复定义的provider、ping、SNMP、SSH函数,保留一份有效逻辑即可。
内容的提问来源于stack exchange,提问作者Depfryer
相关产品推荐
相关产品推荐

