簡體   English   中英

使用multiprocessing.pool異步ping

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM