You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用subprocess.Popen结合线程实现ping设备功能返回错误结果求助

问题分析与修复方案

核心问题

你的代码在多线程环境下出错的根本原因是全局列表ping_cmd被多个线程共享并修改:

  • ping_cmd是全局变量,每次调用ping_ip(ip)都会执行ping_cmd.append(ip),当多个线程并行执行时,这个列表会不断追加IP地址,导致最终的ping命令格式完全错误(比如变成ping -c 4 -W 2 192.168.0.100 192.168.0.1 ...),根本无法正确执行ping操作。
  • 额外问题:使用集合{ip, result}存储结果,这会导致键值对无序且格式混乱,应该用字典{ip: result}。

修复代码

修改ping.py

from utilities.env import PACKET_COUT, PING_TIME, MAX_WORKERS_COUNT
from utilities.cmds import create_ping_cmd
from subprocess import Popen, PIPE, DEVNULL, TimeoutExpired
from re import findall
from concurrent.futures import ThreadPoolExecutor

MAX_PING_TIME = float(PACKET_COUT) * float(PING_TIME)

def check_ping_process(ping_process):
    try:
        out = ping_process.communicate(timeout=MAX_PING_TIME)[0]
        # 检查是否有TTL字段(表示收到响应)
        has_ttl = bool(findall(r"TTL", out))
        return ping_process.returncode == 0 and has_ttl
    except TimeoutExpired:
        ping_process.kill()
        return False

def ping_ip(ip):
    # 每次调用都创建新的ping命令列表,避免全局变量共享冲突
    ping_cmd = create_ping_cmd()
    ping_cmd.append(ip)
    ping_process = Popen(
        ping_cmd,
        stdout=PIPE,
        stderr=DEVNULL,
        text=True
    )
    return check_ping_process(ping_process)

def ping_ip_list(ip_list):
    ping_results = []
    with ThreadPoolExecutor(max_workers=MAX_WORKERS_COUNT) as executor:
        results = executor.map(ping_ip, ip_list)
        for ip, result in zip(ip_list, results):
            result_dict = {ip: result}
            print(result_dict)
            ping_results.append(result_dict)
    return ping_results

可选优化main.py(让结果可返回/查看)

from ping import ping_ip_list

ip_list = [
    '192.168.0.100',
    '192.168.0.1',
    '192.168.0.104',
    '192.168.0.124',
    '192.168.0.103'
]

def monitor_network_devices(ip_list):
    results = ping_ip_list(ip_list)
    return results

# 调用并打印结果
if __name__ == "__main__":
    device_status = monitor_network_devices(ip_list)
    print("\n最终检测结果:")
    for status in device_status:
        print(status)

修复说明

  1. 移除全局ping_cmd:在ping_ip函数内部每次创建新的命令列表,确保每个线程使用独立的ping命令,避免多线程间的变量干扰。
  2. 修正结果存储格式:用字典{ip: result}替代集合,保证结果的键值对应关系清晰。
  3. 简化check_ping_process逻辑:去掉无用的ping_result字典,直接返回布尔值,代码更简洁。

内容的提问来源于stack exchange,提问作者Makhsudjon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:45:28