[英]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.