Python多线程

Python有很多多线程的模块,好坏不一。在缺乏系统线程知识的情况下,逐一试用吧。

threading

背景:写了一个用python-nmap查找在线主机的脚本。ip地址是从dhcpd的dhcpd.leases里面用正则表达式匹配出来的。然后把ip放到alive_state函数里面查找up的主机。屏蔽了dhcpd的内容为了不泄漏公司信息。

代码:


# 查找up的ip,其实就是用nmap的ping查找
# 考虑到windows主机会屏蔽ping,所以再用windows_os_alive函数再过滤一遍
def find_alive(host):
    nm = nmap.PortScanner()
    nm.scan(hosts=host, arguments='-sP')
    up_hosts = int(nm.scanstats()['uphosts'])
    if up_hosts:
        return True
    else: # Windows OS blocked ping check, run check with port detection again
          # to make sure know windows is alive
        if windows_os_alive(host):
            return True
        return False

# 检测windows
def windows_os_alive(host):
    nm = nmap.PortScanner()
    nm.scan(hosts=host, arguments='-PN -p 135')
    up_hosts = int(nm.scanstats()['uphosts'])
    if up_hosts:
        return True
    else:
        return False
 

# 用了Django的model来操作数据库,因为我的sql很差
def save_into_db(mac_addr, mac_timestamp, mac_ip, mac_state): 
    try:
        mac.objects.get(mac=mac_addr)
        mac.objects.filter(mac=mac_addr).update(ip_addr=mac_ip, state=mac_state,
            timestamp=mac_timestamp)
    except mac.DoesNotExist:
        p = mac(mac=mac_addr, ip_addr=mac_ip, state=mac_state,
            timestamp=mac_timestamp, serial_number=DEF_ASSET_INSTANCE)
        p.save()

# 多线程的类,重点再这里吧
class handle_entries(threading.Thread):
    # 初始化一下
    def __init__(self, mac, mac_detail):
        threading.Thread.__init__(self)
        self.mac = mac
        self.mac_detail = mac_detail

    # 因为是用的threading,所以要自己写run,也符合这个案例的需求,因为我想同时再终端输出过程。不过多线程的情况下,输出是乱的,因为不是按序操作。
    def run(self):
        if (NOW - self.mac_detail['timestamp']) <= 43200: # only test alive with hosts in
                                                          # two days
            if find_alive(self.mac_detail['ip']):
                alive_state = 'Alive'
            else:
                alive_state = 'Offline'
        else:
            alive_state = 'Depercated'
        # add alive stats into result
        dhcp_result[self.mac]['state'] = alive_state
        ip_tab = ' ' * (15 - len(self.mac_detail['ip']))
        oneline_string = '| {} | {} | {}{} | {} |'.format(
            self.mac, self.mac_detail['timestamp'], self.mac_detail['ip'], ip_tab, alive_state)
        save_into_db(self.mac, self.mac_detail['timestamp'], self.mac_detail['ip'], alive_state)
        print oneline_string
        # print '-' * len(oneline_string)


if __name__ == '__main__':
    start_time = time.time()
    dhcp_result = filter_dhcp_client()
    print '=' * 80
    print 'Total collected: {}'.format(len(dhcp_result))
    print '=' * 80
    threads = [] # 先开一个空的列表来存放所有进程
    for k, v in dhcp_result.items():
        threads.append(handle_entries(k, v)) # 一口气把所有要查询的ip都放到进程里面
    for t in threads: # 用循环一个个启动进程,其实就是run()里面的内容
        t.start()
    for t in threads: # 看了很多例子都说用join是为了等待进程结束。因为我这里最后要打印耗时和一些额外的信息,所以我也用join
        t.join()
    print '=' * 80
    end_time = time.time()
    print '{} find_alive threads are loaded!'.format(len(threads))
    print 'Time cost: {}s'.format(end_time - start_time)
    # wirte into file with json
    with open('./dhcp_result.json', 'w') as f:
        f.write(json.dumps(dhcp_result))


你可能感兴趣的:(Python)