[英]Async ping with multiprocessing.pool
我试图使用Windows上的 multiprocessing.pool作为较大程序的一部分ping Python中的数百个设备 。 响应被解析为成功案例和失败案例(即请求超时,或主机不可达)。
下面的代码工作正常,但是,程序的另一部分从响应中获取平均值,并使用从数据库中获取的先前结果来计算滚动平均值。
滚动平均函数偶尔会在int(new_average)
上失败,因为传入的new_average是None类型。 请注意,滚动平均函数仅在成功情况下计算。
我认为该错误一定是在解析函数中(这似乎不太可能),或者是我使用multiprocessing.pool的方式。
我的问题 :我是否正确使用多处理? 更一般而言,是否有更好的方法来实现此异步ping? 我已经看过使用Twisted了,但是我没有看到任何ICMP协议实现(GitHub上有txnettools ,但是我不确定它的正确性,并且看起来也不再维护)。
节点对象如下所示:
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
我建议您使用gevent( http://www.gevent.org ,基于libev和greenlet协程的异步I / O库)代替多处理。
事实证明,有一个适用于gevent的ICMP实现: https : //github.com/mastahyeti/gping
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.