运维少年系列 python and cisco (4)

骚年 运维少年

运维少年系列 python and cisco (4)

说明

本章使用了多线程的方式提高脚本执行的效率,本章也是本系列文章的最后一个内容。回顾前三章,从单台交换机到多台交换机然后到异常处理,到今天的多线程,我觉得还算比较连贯吧~

多线程

为什么要使用多线程?在前面我们写的所有程序都是单线程的,串行执行,也就是说,要等上一个命令执行完成之后,下一个命令才能执行,但很显然,在机器比较多的情况下显得效率很低。所以我们应该使用多线程,使程序并发执行。

单线程和多线程比较

  • 单线程执行时间
    来看看上一次写的脚本的执行时间吧(动图)~

可以看到,需要28s,这仅仅是三台机器啊~如果100台呢,那也太久了吧~

  • 多线程执行时间
    来看看多线程的执行时间是多少吧(动图)~

可以看到,使用了多线程之后,速度提升了很多~

多线程使用

多线程的简单使用

python中的多线程实现使用的是threading函数,但是在使用多线程的时候,可能会遇到很多问题。先来看看多线程简单的用法吧

import threading  # 导入多线程模块import timedef run(num):  # 定义函数(必须)    print 'this is the thread ', num    time.sleep(1)for i in range(20):    t = threading.Thread(target=run,args=(i,))  # 实例化,target表示需要使用多线程的函数名,args为传入的参数,必须为元组,所以如果只有一个参数,需要加,号    t.start() #运行

多线程需要考虑的问题

在使用多线程的时候,线程之间会抢占资源,不按顺序执行,比如:在连接主机的时候,我们希望从连接到连接成功之前,目标IP保持不变,很显然,如果连接的时候目标IP发生变化,会导致连接出错或者验证失败。比如

import paramikoimport socketimport timeimport threadingstarttime = time.time()user = 'yunwsn'passwd = '123456's = paramiko.SSHClient()s.set_missing_host_key_policy(paramiko.AutoAddPolicy())IP = file('IP.txt','rb')def run(ip): # 定义函数    try:        s.connect(ip,username=user,password=passwd,timeout=5,look_for_keys=False,allow_agent=False)        print '[ \033[0;32m success\033[0m ] login %s ' %ip        cmd = s.invoke_shell()        command = file('command.txt','rb')        for command in command.xreadlines():            cmd.send(command)            time.sleep(0.3)            output = cmd.recv(65535)            print output        cmd.close()    except paramiko.ssh_exception.NoValidConnectionsError:        print '[ \033[0;31m failed \033[0m ] Unable to connect to %s ' % ip    except socket.error,err:        print '[ \033[0;31m failed \033[0m ] %s to %s' %(err,ip)    except paramiko.ssh_exception.AuthenticationException:        print '[ \033[0;31m failed \033[0m ] Authentication failed on %s' % ipfor i in IP.xreadlines():  # 循环IOP        t = threading.Thread(target=run, args=(i,)) # 多线程实例化        t.start()  # 启用多线程IP.close()

执行效果如下:

[root@yunwei cisco]# python ywsn_p_c_lab4.py [  failed  ] Authentication failed on 192.168.108.252[  failed  ] Authentication failed on 192.168.108.253[  failed  ] Authentication failed on 192.168.108.251[root@yunwei cisco]# 

这时候我们就需要用到RLock办法了,RLock可以在指定的范围内锁定值,保证这个值使不会被修改。很明显在我们这个程序用,我们要在s.connect(ip,username=user,password=passwd,timeout=5,look_for_keys=False,allow_agent=False)这里进行数据锁定,直到它连接成功。

  • 如何锁定数据
    那怎么锁定呢?这需要使用到RLock办法,具体使用如下:
lock = threading.RLock()  # 实例化lock.acquire() # 开始锁定lock.release() # 解锁

我们只需要在开始锁定和解锁之间加上程序需要锁定值的代码即可

def run(ip):    try:        lock.acquire()        s.connect(ip,username=user,password=passwd,timeout=5,look_for_keys=False,allow_agent=False)        lock.release()        print '[ \033[0;32m success\033[0m ] login %s ' %ip

对于命令来说也是一样的,在执行命令的时候,需要锁定该值,不然会出现以下情况:

Sw2(config)#name V80Sw1(config-vlan)#vlan 100Sw3(config-vlan)#int e0/1Sw2(config-if)#vlan 90Sw1(config-vlan)#name V100Sw3(config-vlan)#switchport mode accessSw2(config-if)#name V90Sw1(config-vlan)#exitSw3(config)#switchport trunk encapsulation dot1q

数据全部乱了…

实现代码

import paramikoimport socketimport timeimport threadinguser = 'yunwsn'passwd = '123456's = paramiko.SSHClient()s.set_missing_host_key_policy(paramiko.AutoAddPolicy())IP = file('IP.txt','rb')lock = threading.RLock()def run(ip):    try:        lock.acquire()        s.connect(ip,username=user,password=passwd,timeout=5,look_for_keys=False,allow_agent=False)        lock.release()        print '[ \033[0;32m success\033[0m ] login %s ' %ip        cmd = s.invoke_shell()        command = file('command.txt','rb')        for command in command.xreadlines():            lock.acquire()            cmd.send(command)            lock.release()            time.sleep(0.3)            output = cmd.recv(65535)            print output        cmd.close()    except paramiko.ssh_exception.NoValidConnectionsError:        print '[ \033[0;31m failed \033[0m ] Unable to connect to %s ' % ip    except socket.error,err:        print '[ \033[0;31m failed \033[0m ] %s to %s' %(err,ip)    except paramiko.ssh_exception.AuthenticationException:        print '[ \033[0;31m failed \033[0m ] Authentication failed on %s' % ipfor i in IP.xreadlines():        t = threading.Thread(target=run, args=(i,))        t.start()IP.close()
  • 效果(动图)
©著作权归作者所有:来自51CTO博客作者mb5ffd6f0f39006的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 2021-03-11:go中,协程内部再启用协程,它们是没关系,对吧?外部协程奔溃
  2. 记一次Oracle数据更新经历
  3. SQL高级知识V2——动态SQL
  4. ansible初入
  5. SQL存储过程的详细用法,不信你看不懂
  6. c语言自学打卡
  7. hive 本机测试使用local模式可以加快执行效率
  8. 一文读懂MySQL的执行计划EXPLAIN
  9. ||运算你真的了解吗?

随机推荐

  1. Android framwork 锁屏界面开发 笔记
  2. 页面跳转采用滑动效果
  3. android文件操作的实例
  4. android 判断横竖屏的方法
  5. android之Matrix
  6. Android中的Message类以及Java对象池的实
  7. 2011.09.07——— android zxing 条形码
  8. android 9.0 增加实体按键的按键声音,以及
  9. android 创建快捷方式图标
  10. android源码分享之蓝虫火车票余票查询源