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

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

说明

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

多线程

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

单线程和多线程比较

  • 单线程执行时间

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

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

  • 多线程执行时间

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

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

多线程使用

多线程的简单使用

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()
  • 效果(动图)

微信公众号:运维少年

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值