使用multiprocessing.pool进行异步ping

时间:2014-02-20 19:40:44

标签: python windows multiprocessing twisted ping

我正在尝试使用 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

1 个答案:

答案 0 :(得分:1)

我建议你使用gevent(http://www.gevent.org,基于libev和greenlet协同程序的异步I / O库)而不是多处理。

事实证明,gevent实现了ICMP: https://github.com/mastahyeti/gping