我正在尝试使用 Windows 上的 multiprocessing.pool 在Python中 ping几百个设备,作为更大程序的一部分。响应被解析为成功案例和失败案例(即请求超时或主机无法访问)。
下面的代码运行正常,但是,程序的另一部分从响应中获取平均值,并计算从数据库中获取的先前结果的滚动平均值。
滚动平均功能偶尔会在int(new_average)
失败,因为传入的new_average是无类型。请注意,滚动平均功能仅在成功案例中计算。
我认为错误必须在解析函数中(这似乎不太可能),或者我如何使用multiprocessing.pool。
我的问题:我正确使用多处理吗?更一般地说,有没有更好的方法来实现这种异步ping?我已经看过使用Twisted,但我没有看到任何ICMP协议实现(GitHub上有txnettools,但我不确定这是否正确,并且它看起来不再保持。)< / p>
节点对象如下所示:
class Node(object):
def __init__(self, ip):
self.ip = ip
self.ping_result = None
# other attributes and methods...
以下是异步ping代码的想法:
import os
from multiprocessing.pool import ThreadPool
def parse_ping_response(response):
'''Parses a response into a list of the format:
[ip_address, packets_lost, average, success_or_failure]
Ex: ['10.10.10.10', '0', '90', 'success']
Ex: [None, 5, None, 'failure']
'''
reply = re.compile("Reply\sfrom\s(.*?)\:")
lost = re.compile("Lost\s=\s(\d*)\s")
average = re.compile("Average\s=\s(\d+)m")
results = [x.findall(response) for x in [reply, lost, average]]
# Get reply, if it was found. Set [] to None.
results = [x[0] if len(x) > 0 else None for x in results]
# Check for host unreachable error.
# If we cannot find an ip address, the request timed out.
if results[0] is None:
return results + ['failure']
elif 'Destination host unreachable' in response:
return results + ['failure']
else:
return results + ['success']
def ping_ip(node):
ping = os.popen("ping -n 5 "+node.ip,"r")
node.ping_result = parse_ping_response(ping.read())
return
def run_ping_tests(nodelist):
pool = ThreadPool(processes=100)
pool.map(ping_ip, nodelist)
return
if __name__ == "__main__":
# nodelist is a list of node objects
run_ping_tests(nodelist)
一个示例ping响应供参考(来自Microsoft docs):
Pinging 131.107.8.1 with 1450 bytes of data:
Reply from 131.107.8.1: bytes=1450 time<10ms TTL=32
Reply from 131.107.8.1: bytes=1450 time<10ms TTL=32
Ping statistics for 131.107.8.1:
Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),
Approximate roundtrip times in milliseconds:
Minimum = 0ms, Maximum = 10ms, Average = 2ms
答案 0 :(得分:1)
我建议你使用gevent(http://www.gevent.org,基于libev和greenlet协同程序的异步I / O库)而不是多处理。
事实证明,gevent实现了ICMP: https://github.com/mastahyeti/gping