使用python eventlet并发ping

使用python的eventlet实现并发ping主机

import threading
import os
import re
import socket
import subprocess
import sys
import time
import eventlet
from eventlet import GreenPool

eventlet.monkey_patch()

pool = GreenPool(100)


class Counter(object):

    def __init__(self):
        self.lock = threading.Lock()
        self.success_num = 0
        self.fail_num = 0

    def success(self):
        if self.lock.acquire():
            self.success_num += 1
            self.lock.release()

    def fail(self):
        if self.lock.acquire():
            self.fail_num += 1
            self.lock.release()

    def reset(self):
        self.success_num = self.fail_num = 0

    def __str__(self):
        s = "success: %s\nfail: %s" % (self.success_num, self.fail_num)
        return s


BATCH_COUNTER = Counter()


def execute_cmd(cmd):
    sub_pro = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    sub_pro.wait()
    output = "\n".join(sub_pro.communicate())
    return sub_pro.returncode, output


def executor(func, *args):
    try:
        if func(*args):
            BATCH_COUNTER.success()
            return True
    except Exception as e:
        pass
    BATCH_COUNTER.fail()
    return False


def exec_batch(func, l_args):
    start_time = time.time()
    for args in l_args:
        if isinstance(args, (list, tuple)) is False:
            args = [args]
        pool.spawn(executor, func, *args)
    print("exec batch completed. wait ...")
    pool.waitall()
    print(BATCH_COUNTER)
    end_time = time.time()
    use_time = end_time - start_time
    print("use time: %s" % use_time)
    BATCH_COUNTER.reset()


def demo_func(num):
    if num > 0:
        return True
    return False


def get_default_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("114.114.114.114", 53))
    return s.getsockname()[0]


def read_ip_file(ip_file):
    ips = []
    with open(ip_file, "r") as ri:
        content = ri.read()
        lines = content.split("\t")
        for line in lines:
            line = line.strip()
            if len(line) > 0:
                fa = re.findall(r"\d+\.\d+\.\d+\.\d+", line)
                ips.extend(fa)
        return ips


def ping_func(ip):
    cmd = ["ping", "-c", "5", "-W", "5", ip]
    code, output = execute_cmd(cmd)
    if code == 0:
        print("success %s" % ip)
        return True
    print("fail %s" % ip)
    return False


if __name__ == "__main__":
    """
    example 1:
    python batch_ping.py ip.text
    example 2:
    python batch_ping.py 10.10.10.1 10.10.10.2 10.10.10.3
    """
    argv = sys.argv
    l_ip = []
    if len(argv) == 1:
        local_ip = get_default_ip()
        ip_prefix = local_ip.rsplit(".", 1)[0]
        for i in range(1, 255):
            l_ip.append("%s.%s" % (ip_prefix, i))
    elif len(argv) == 2:
        ip_file = argv[1]
        l_ip = read_ip_file(ip_file)
    else:
        l_ip.extend(argv[1:])
    exec_batch(ping_func, l_ip)



你可能感兴趣的:(python)