day09 threading, paramiko, queue 模块
1 模拟ssh
2 锁 内部锁,程序锁,信号量
3 多线程
4 简单消息队列
先来看模拟ssh ,python 的强大之处就是因为有很多模块,可以很简单的完成复杂的事情,今天我们用paramiko 模块来模拟一个ssh 的交互
ssh: 只可远程执行linux 服务(或者是有ssh 服务的系统)
1 先简单执行命令测试下
#!/usr/bin/env python3
# Author: Shen Yang
import paramiko
#help(paramiko)
#实例化一个客户端
ssh = paramiko.SSHClient()
#允许未登陆过的登陆
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#连接远程主机
ssh.connect(hostname='192.168.81.133',port=22,username='root',password='7758521')
#执行命令,收集三种结果,标准输入,标准输出,标准错误
stdin,stdout,stderr = ssh.exec_command('uptime')
#获取结果,转码
result = stdout.read().decode()
result_err = stderr.read().decode()
#打印
print(result)
if result_err:
print('error!',result_err)

是不是很激动! 确实,这样感觉太好了,有点类似于slat 的感觉了!
解释一下上面的:
stdin,stdout,stderr = ssh.exec_command('uptime')
我们看到三个变量,
stdin 是获取输入的值,这里并没有。
stdout 是获取标准输出,就像我们在shell 下执行命令获取到的正确结果,为什么说是正确结果呢?因为
stderr 是获取当命令执行错误后的结果的。
这里并不支持交互性的命令比如top 什么的,如果非用top 记得加上 -bn 1
import paramiko
#建立一个通道
transport = paramiko.Transport(('192.168.81.133',22))
transport.connect(username='root',password='7758521')
#从这个通道开始传输文件
sftp = paramiko.SFTPClient.from_transport(transport)
# 将本地文件scp_client.py传输至远程服务器/tmp/yuanduan.py
sftp.put('scp_client.py','/tmp/yuanduan.py')
#将远端文件/tmp/yuanduan.py下载至本地/tmp/yuanduan.py
sftp.get('/tmp/yuanduan.py','/tmp/yuanduan.py')
结果:

上面的是使用密码方式,那么我们是否可以使用密钥方式来连接远端服务器呢?答案是肯定的
#!/usr/bin/env python3
# Author: Shen Yang
import paramiko
#指定Key 文件路径
key_file = paramiko.RSAKey.from_private_key_file('mykey')
host = '192.168.1.201' #创建客户端对象
ssh = paramiko.SSHClient()
#允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#连接服务器
ssh.connect(hostname=host,port=22,username='root', key_filename='mykey') #执行命令
stdin,stdout,stderr = ssh.exec_command('uptime') #获取命令结果
result = stdout.read()
print(result.decode())
#关闭连接
ssh.close()

好了,关于模拟ssh 的paramiko 模我们先用到这里,以后再用到其他功能再细研究吧。。
下面开始讲线程和进程,比较重要!
先将线程,什么是线程呢(thread)?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
画个图来表示一下:

每一个程序的内存是独立的
每一个程序一个进程:
对各种资源管理的集合就可以称为 进程。
线程: 是操作系统最小的调度单位,是一串指令的集合。


对于一个主线程的修改可能会影响同一进程下的其他线程。
创建子进程相当于对父进程的克隆

让我们实践的操作一下,下面是一个简单的事例,证明一下这是一个并发的操作:
#!/usr/bin/env python3
# Author: Shen Yang
import threading,time
def run(n):
print('this is ',n)
time.sleep(2)
#实例化两个任务, target 是要执行的任务, args 是传入的参数,是一个元组,即便是一个参数也要使用,分割
t1 = threading.Thread(target=run,args=('t1',))
t2 = threading.Thread(target=run,args=('t2',))
#运行
t1.start()
t2.start()

#定义一个类,继承Thread
class MyThread(threading.Thread):
def __init__(self,n):
super(MyThread, self).__init__()
self.n = n
def run(self):
print('running task ',self.n)
time.sleep(2) #实例化两个任务
t1 = MyThread('t1')
t2 = MyThread('t2') #启动
t1.start()
t2.start()
结果同上
那么我们是否可以计算所有线程的结束时间吗,可以的:
#!/usr/bin/env python3
# Author: Shen Yang
import threading,time #定义任务过程
def run(n):
print('this is ',n)
time.sleep(2) #记住开始时间
start_time = time.time() #设置空对象列表
obj_list = []
#生成每个对象执行并把对象加入列表中
for i in range(50):
t = threading.Thread(target=run,args=(i,))
t.start()
obj_list.append(t)
#循环列表里的对象来等待所有对象执行完毕
for t in obj_list:
t.join()
#等所有对象执行完毕后执行计算时间
print('cost:',time.time() - start_time)

打印主线程:

打印子线程:

打印活动的线程个数:
守护进程:
守护进程是仆人,主进程是主人,主人退出,守护进程也要退出。
socket server 可以设置守护线程,这样在手动退出的时候不会等待其他线程结束就退出。
实践:
#!/usr/bin/env python3
# Author: Shen Yang
import threading,time end_list = [] def run(n):
print('this is ',n)
time.sleep(1)
end_list.append(n) start_time = time.time() #设置空对象列表
obj_list = []
#生成每个对象执行并把对象加入列表中
for i in range(5000):
t = threading.Thread(target=run,args=(i,))
t.setDaemon(True)
t.start()
obj_list.append(t) #等所有对象执行完毕后执行计算时间
print('cost:',time.time() - start_time)
time.sleep(0.8) #print(end_list)
print(len(end_list))
可以看到,执行了一半就终止了,其他的被强制退出了

接下来,讲一下lock



线程锁(互斥锁Mutex)
一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况?

其实信号量就是一个特殊的锁,可以允许多个线程的锁


说白了就是和锁相反:同一时间最多可以有几个线程修改数据
#!/usr/bin/env python3
# Author: Shen Yang
import threading,time
def run(n):
semaphore.acquire()
time.sleep(1)
print('run the thread:{_n}\n'.format(_n=n))
semaphore.release()
if __name__ == '__main__':
semaphore = threading.BoundedSemaphore(5)
for i in range(22):
t = threading.Thread(target=run,args=(i,))
t.start()
while threading.active_count() != 1:
pass
else:
print('-----all threads done-------')
看下效果:

事件:
Events
用于线程之间的数据同步,

一个红灯停绿灯行的例子:



实践一下:
#!/usr/bin/env python3
# Author: Shen Yang
import threading,time #实例化一个event
event = threading.Event() #定义红绿灯
def lighter():
count = 0
event.set() #设置标志位
while True:
if count >5 and count <10: #判断更改标志位
event.clear() #清理
print('\033[41;1mred light is on ...\033[0m')
elif count >10:
event.set() #设置
count = 0 #归0
else: #其他为设置状态
print('\033[46;1mgreen light is on ...\033[0m')
time.sleep(1)
count += 1 #定义汽车
def car(name):
while True:
if event.is_set(): #有设置
print('{_name} running ...'.format(_name = name))
time.sleep(1)
else:
print('{_name} see the red light ,waiting ...'.format(_name = name))
event.wait()
print('\033[46;1m{_name} see green light is on,start going ...\033[0m'.format(_name = name)) #启动灯
light = threading.Thread(target=lighter,)
light.start() #启动汽车
car1 = threading.Thread(target=car,args=('Tesla',))
car2 = threading.Thread(target=car,args=('Fit',))
car3 = threading.Thread(target=car,args=('Civic',))
car1.start()
car2.start()
car3.start()
看下效果:




使用 get_nowait() 通过判断异常知道队列为空

也可以实现:

可以等待:

可以设置队列长度:

后入先出:


优先级越低越优先


生产者:

消费者:

执行:

day09 threading, paramiko, queue 模块的更多相关文章
- 用threading和Queue模块实现多线程的端口扫描器
一.Queue模块基础 q = Queue.Queue() q.qsize() 返回队列的大小 q.empty() 如果队列为空,返回True,反之Fals ...
- threading模块和queue模块实现程序并发功能和消息队列
简介: 通过三个例子熟悉一下python threading模块和queue模块实现程序并发功能和消息队列. 说明:以下实验基于python2.6 基本概念 什么是进程? 拥有独立的地址空间,内存,数 ...
- python-网络安全编程第六天(threading多线程模块&Queue模块&subprocess模块)
前言 昨天晚上9点多就睡了 2点起来没睡意... 那就学习吧emmmm ,拿起闲置几天的python课程学习.学习到现在5.58了 总结下 继续开始学习新的内容 多多线程? 线程(英语:thread) ...
- 【Python@Thread】queue模块-生产者消费者问题
python通过queue模块来提供线程间的通信机制,从而可以让线程分项数据. 个人感觉queue就是管程的概念 一个生产者消费者问题 from random import randint from ...
- Python之Queue模块
Queue 1.创建一个“队列”对象 >>> import Queue >>> queue = Queue.Queue(maxsize=100) >>& ...
- python --- queue模块使用
1. 什么是队列? 学过数据结构的人都知道,如果不知道队列,请Google(或百度). 2. 在python中什么是多生产者,多消费模型? 简单来说,就是一边生产(多个生产者),一边消费(多个消费者) ...
- 【Python】 多线程并发threading & 任务队列Queue
threading python程序默认是单线程的,也就是说在前一句语句执行完之前后面的语句不能继续执行(不知道我理解得对不对) 先感受一下线程,一般情况下: def testa(): sleep(1 ...
- day43-python消息队列二-queue模块
Python提供了Queue模块来专门实现消息队列Queue对象 Queue对象实现一个fifo队列(其他的还有lifo.priority队列,这里不再介绍).queue只有maxsize一个构造参数 ...
- Python中Queue模块及多线程使用
Python的Queue模块提供一种适用于多线程编程的FIFO实现.它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个 ...
随机推荐
- python基础之循环语句
一.if条件语句: 语法: 1.if单分支(单重条件判断) if expression: expr_true_suite 注释:expession为真执行代码expr_true_suite if单分支 ...
- LeetCode OJ 3Sum 3个整数之和
题意:给一个vector<int>容器,要求每当找到3个元素之和为0时就将这3个数按大小顺序记下来,用一个二维vector返回.也就是vector< vector<int> ...
- linux 命令——38 cal (转)
cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳历”又名“太阳历”,系以地球绕行太阳一周为一年,为西方各国所通用,故又名“西历”. 1.命令格式: cal ...
- 如何在SAP Cloud for Customer自定义BO中创建访问控制
文章作者: Yi 已获得Yi的转载许可. 访问控制方式和使用注意事项 1. C4C中的访问控制有两种方式 RelevantForAccessControl AccessControlContext 2 ...
- PHP:php遍历数组each()方法总结
each()的作用是将数组当前元素的键值对拆成一个新数组,并把下一个元素作为当前元素.比如Array(...,'Robert'=>'Bob',...)中的'Robert'=>'Bob'键值 ...
- UVA 10375 Choose and divide(大数的表示)
紫上给得比较奇怪,其实没有必要用唯一分解定理.我觉得这道题用唯一分解只是为了表示大数. 但是分解得到的幂,累乘的时候如果顺序很奇怪也可能溢出.其实直接边乘边除就好了.因为答案保证不会溢出, 设定一个精 ...
- POJ 3421 X-factor Chains(构造)
这条链依次乘一个因子.因为n<2^20,sqrt(n)分解因子,相同的因子相对顺序取一个. 组合公式计算一下就好. #include<cstdio> #include<iost ...
- hdu-1233 还是畅通工程---MST模板
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1233 题目大意: 求MST最小生成树 解题思路: Prim算法直接套即可 #include<b ...
- 【洛谷1486】[NOI2004] 郁闷的出纳员(Splay的小运用)
点此看题面 大致题意: 你是一个公司的出纳员,现在有\(n\)个操作,操作有4种:新来一个员工.增加全体员工工资.减少全体员工工资.查询第\(k\)多的工资.若一个员工的工资在某一时刻低于合同上的工资 ...
- 使ListView控件中的选择项高亮显示
实现效果: 知识运用: ListView控件的SelectedItems属性 //获取在ListView控件中被选中数据项的集合 public ListView.SelectedListViewIte ...