ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-03-11 22:56:28  阅读:184  来源: 互联网

标签:cisco 运维 python ip failed IP print 033 多线程


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

骚年 运维少年

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

说明

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

多线程

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

单线程和多线程比较

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

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

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

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

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

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

多线程使用

多线程的简单使用

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


import threading  # 导入多线程模块
import time

def 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 paramiko
import socket
import time
import threading
starttime = 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' % ip

for 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 V80
Sw1(config-vlan)#
vlan 100
Sw3(config-vlan)#
int e0/1
Sw2(config-if)#
vlan 90
Sw1(config-vlan)#
name V100
Sw3(config-vlan)#
switchport mode access
Sw2(config-if)#
name V90
Sw1(config-vlan)#
exit
Sw3(config)#
switchport trunk encapsulation dot1q

数据全部乱了…

实现代码


import paramiko
import socket
import time
import threading
user = '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' % ip

for i in IP.xreadlines():
        t = threading.Thread(target=run, args=(i,))
        t.start()
IP.close()
  • 效果(动图)
    运维少年系列 python and cisco (4)

标签:cisco,运维,python,ip,failed,IP,print,033,多线程
来源: https://blog.51cto.com/15082392/2656476

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有