Python多线程

来源:互联网 发布:ios 提取数组相同元素 编辑:程序博客网 时间:2024/06/06 03:05

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# 检测windowsdef 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))


0 0