python_paramiko模块 / ssh 密钥 / 进程与线程 / 多线程 / 主线程与子线程 / 线程锁、信号量 / Event / Queue
python边写边更…
一、鸡汤:
(写完再写…)
二、paramiko模块:
1.SSHCilent:
(用于连接远程服务器,并执行基本命令;将客服端“client”封装成SSH) (下的包有问题…真的服了)
#Author:Jony c
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
ssh = paramiko.SSHClient()
#允许连接不在known_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#连接
ssh.connect(hostname= "c1.salt.com",port=22,username=“wupeiqi”,password=“123”)
#执行命令
stdin,stout,stderr = ssh.exec_command("dir")
#获取命令结果
result = stout.read()
#关闭连接
ssh.close()
#允许连接不在known_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
(这个kown_hosts为其双方建立一种,安全协议;下面报错是在kown_host没有找到“我要添加的那台机器”;上面那条语句就是如果没有找到,就自动添加…)
stdin ,stdout,stderror = ssh.exec_comand("dir")
res =stdout.read()
error =stderror.read()
#三元运算
result = res if res else error
2.TCPCilent:
#Author:Jony c
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
#连接端口
transport = paramiko.Transport(("hostname",22))
transport.connect(username="wupeiqi",password="123")
sftp = paramiko.SFTPClient.from_transport(transport)
#上传
sftp.put("本地文件路径","服务器路径")
#下载
sftp.get("服务器路径","本地文件路径",)
3.SSH密钥:
(用户名、密码不是很安全;密钥:公钥,私钥,公钥放在你要“连接的主机”,私钥自己留着,公钥和私钥是一对)
1.生成密钥(ssh.keygen)(老师操作是在虚拟机上的…windows上不好使…Linux也没学过qaq)
(id_rsa)你的私钥:
(id_rsa.pub)公钥:
(存在哪呢??1.你要登录那个用户:例如“Alex” 2.家目录下的authoized_keys)
(目录权限)
(改权限;chomd 777)
(r:访问 w:修改 x:执行)
ssh.connect(hostname= "c1.salt.com",port=22,username=“wupeiqi”,password=“123”,pkey = private_key)
transport.connect(username="wupeiqi",password="123",pkey = private_key)
三、多线程:
1.进程与线程:
①:线程:线程是操作系统(OS)运算调度的最小单位,一个进程可以并发多个线程,每个线程并发的执行不同任务…
②:线程:是一堆指令的集合,操作系统(OS)对CPU发送的一堆指令,告诉CPU执行什么样的操作;
③:每一个程序的“内存”相互独立,每一个程序在运行时,OS都会给其开辟相应的“内存空间”;
④:进程:运行程序(QQ) 要以一个整体的形式,暴露给操作系统(OS);包括里面对"各种资源的调用"、内存的调用、网卡的调用…,例如:qq在运行时,os给它开辟一个内存空间、qq还调用网卡传输数据…等这个程序都会占用很多资源;
⑤:进程要“操作”CPU,必须创建一个线程
1.线程就是一段执行的context(上下文,指令),CPU要执行的所有信息流; 2.假如:你读一本书,你想休息一下,你回来的时候,你想回到你读到哪了的精确点(书页、行数、字数);所以你要执行的context对于你读书至少要有三个数字; 3.如果你的室友,用同样的方式,记下“书签”;当你不用的时候,它可以拿走; 4.线程也是同样的方法工作,(CPU给你一种“幻觉”),单核只能可以干一件事(“contest”,上下文的切换);由于CPU的运算速度太快,所以感觉是在同时执行多个任务; 5.所有在同一个“进程”里的线程,共享同一块内存空间;
1.进程有唯一的“进程标识符”(PID);2.一个进程,至少有一个线程;每启动一个进程,都会起一个线程; 3.进程里面的第一个线程,就是主线程;主线程创建子线程,子线程还可以创建其他线程; 4.主线程创建子线程,他们之间是“独立的”;
进程和线程的区别? (1)进程快还是线程快??? 答:没有可比性;进程是所有“资源” 的集合,线程是“一堆指令”(context,上下文);进程要想执行任务,也是通过“线程”,一样快; (2)启动一个“进程”快还是启动一个“线程”快??? 答:线程快(3)线程共享“内存”空间;进程的每一个“内存”都是独立的; (4)父进程创建一个子进程,相当于copy数据;copy完以后,子进程之间的“数据”不共享; (5)线程是访问在进程里的"同一份数据"; (6)同一个进程的线程之间,可以直接“交流”(信息的共享、传递);进程想要“交流”,需要“中间进程”; (7)一个线程可以操作(同一个进程里的)线程;但是,进程只能操作“子进程”; (8)修改了“主线程”,可能会影响其他线程;修改“主进程”,不会影响其他进程;
conclude:线程:是一堆“指令”(contest,上下文),OS可调用的最小单位; (同一个进程)里的线程,共享一片内存空间和数据;之间可以互相操作;主线程修改会影响其他线程;进程:一个程序进行,资源的配置、内存的占用和网卡的调用等(资源的集合);进程之间“相互独立”,子进程copy父进程,父进程修改不影响子进程;
func:
import threading,time
def run(name):
print("%s is running..."%name)#主线程
#1.先起两个“线程”:
t1 = threading.Thread(target=run,args=("刘翔",))#arges必须是元组的形式
t2 = threading.Thread(target=run,args=("苏炳添",))
t1.start()
t2.start()
#2.50个线程“并发,
for i in range(1,51):#每个都是主线程
t = threading.Thread(target=run,args=("%s号运动员"%i,))
t.start()
class:
import threading
class mythread(threading.Thread):
def __init__(self,name):
super(mythread,self).__init__()
self.name = name
def run(self):#这里只能写“run”
print("%s is playing..."%self.name)
man1 = mythread("大熊")
man2 = mythread("胖虎")
man1.start()#和run一样
man2.start()#和run一样
conclude: 1.函数式定义 thread; 2.class(类)定义 thread;
2.主线程和子线程:
(“主线程”创建完“子线程”,就不会管它了),线程是并发的,主线程拉起一个子线程,就会一起并发了…看个例子
import threading,time
def playing(name):
print("%s is playing,玩的很hi!!!"%name)#主线程
time.sleep(1)#子线程,并发都睡1s
print("玩累了...")#子线程
for i in range(10):
t = threading.Thread(target=playing,args=(i,))
t.start()
print("主线程")
print("-----------------------------------")
result:
(“主线程”不会等"子线程")
问题来了:怎么让"主线程"等我的"子线程"???answer: t.join()…#t.wait()
import threading,time
def run(name):
print("%s is running..."%name)#主线程
time.sleep(3)
print("%s is drinking。。。"%name)
#1.先起两个“线程”:
t1 = threading.Thread(target=run,args=("刘翔",))#arges必须是元组的形式
t2 = threading.Thread(target=run,args=("苏炳添",))
t1.start()
t2.start()
t1.join()#我只等t1的子程序
print("-----------------------")
result:
import threading,time
def run(name):
print("%s is running..."%name)#主线程
time.sleep(3)
print("%s is drinking。。。"%name)
#1.先起两个“线程”:
t1 = threading.Thread(target=run,args=("刘翔",))#arges必须是元组的形式
t2 = threading.Thread(target=run,args=("苏炳添",))
t1.start()
t2.start()
t1.join()#我只等t1的子程序
t2.join()#两个一起等
print("-----------------------")
import threading,time
t_list = []
def playing(name):
print("%s is playing,玩的很hi!!!"%name)#主线程
time.sleep(1)#子线程,并发都睡1s
print("玩累了...")#子线程
for i in range(10):
t = threading.Thread(target=playing,args=(i,))
t.start()
t_list.append(t)
for j in t_list:
j.join()#每个都等
print("主线程")
print("-----------------------------------")
(图画的很抽象,为了方便记忆…)
“主线程”不会等"子线程",但是,整个程序会等到“子线程”执行完,即所有程序都跑完,程序才会关闭守护线程:就是设置setDaemon(True),不管你“子线程”了,当我的主线程结束了,整个程序就结束了…
import threading,time
def playing(name):
print("%s is playing,玩的很hi!!!"%name)#主线程
time.sleep(1)#子线程,并发都睡1s
print("玩累了...")#子线程
for i in range(10):
t = threading.Thread(target=playing,args=(i,))
t.setDaemon(True)#设置守护线程,就是不管你
t.start()
print("主线程")
print("-----------------------------------")
conclude: 1.<>主线程 和 子线程 ;那个图可以方便记忆; 2.t.join();等 3.t.setDaemon(True);守护进程
3.python GIL(全局解释器锁):
(enen…这里说一下python的"全局解释器锁"),这是一个python的一个缺陷,无论你是单核、双核、几万核的cpu;对python都是一样的,python在运行时,只会调有一个线程;若像上图这样,python调用4个线程,对一个内存了num = 1 修改 ,四个线程返回的值不一样或者其他问题,都会浪费效率;所以python底层的设置的有GIL(全局解释器锁);python调用的时候,确实会是实在的打在4个核上面,但是只会锁一个“线程”进行调用…
4.线程锁:
import threading,time
num = 0
t_list= []
def playing(name):
global num
num +=1
for i in range(10):
t = threading.Thread(target=playing,args=(i,))
t.start()
t_list.append(t)
for j in t_list:
j.join()
print("主线程")
print("结果",num)
上面程序的结果num,在10个并发线程下,一般正常的是不会得到10(一个空位置,每人给1本书);这是因为那个“假象”导致的; 并不是真正的10个并发“给书”的;上图是具体的运行图;当“线程”安排的很多(1w个),要在规定时间走完1w个,每个线程就会用很少的时间处理num,我从内存里读到num = 0 ,没加完(时间很短);第二个线程开始运行使num加到1,又给了内存;等你下一次又轮到你第一个(没加完的那个)的时候,你会执行上回没“操作完” 的步骤,num其实还是读的0,0+1=1,在给num,再给内存…所以,不会是那种累加的表现
线程锁:就是用来把每一个“线程”锁住,即就是:每个线程让你工作完了,你再去下一个…
import threading,time
lock = threading.Lock()
num = 0
t_list= []
def run(name):
global num
lock.acquire()
num +=1
time.sleep(0.1)
lock.release()
for i in range(10):
t = threading.Thread(target=run,args=(i,))
t.start()
t_list.append(t)
for j in t_list:
j.join()
print("主线程")
print("结果",num)
time.sleep(0.1)
conclude: 1.这个time(0.1)会让程序睡个1s,0.1×10 = 1s; 2.python的“假线程”的并发效果,就是在“很短的”时间完成“单线程”,所以你识别不了; 3.我现在给你锁着,不让你跑,你每个都执行完“0.1s”以后,再给你解锁; 4.所以就出现了,这个程序会花费1s的时间运行;
__author__ = "Alex Li"
import threading, time
def run1():
print("grab the first part data")
lock.acquire()
global num
num += 1
lock.release()
return num
def run2():
print("grab the second part data")
lock.acquire()
global num2
num2 += 1
lock.release()
return num2
def run3():
lock.acquire()
res = run1()
print('--------between run1 and run2-----')
res2 = run2()
lock.release()
print(res, res2)
num, num2 = 0, 0
lock = threading.RLock()#递归锁,防止“嵌套锁”解不开
for i in range(1):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(threading.active_count())
else:
print('----all threads done---')
print(num, num2)
conclude:递归锁,其实和"线程锁"一样的用法,主要是防止“嵌套锁”解不开…
5.semaphore(信号量):
(一次锁多个“线程”,里面有“线程”结束,才会再放进去“线程”;就像你蹲坑一样,一个厕所5个坑,别人上完了…你才能进去上)
import threading,time
def run(name):
lock.acquire()
print("%s is runing..."%name)
time.sleep(2)
lock.release()
lock = threading.BoundedSemaphore(2)
for i in range(10):
t = threading.Thread(target = run,args=(i,))
t.start()
效果:两个进程“一起跑”,就是“两个线程”,并发…
6.Events(事件):
event = threading.Event()
event.set()#设置标志位
event.clear()#清除标志位
event.wait()#有标识位通行,没有标志位“卡死”
#Author:Jony c
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading,time
event= threading.Event()
def lighter():
event.set()
count = 0
while True:
if count > 5 and count <10:
event.clear()
print("\033[31;mthe light is red\033[0m")
elif count > 10:
event.set()
count = 0
else:
print("\033[42;1mthe light is green\033[0m")
count +=1
time.sleep(1)
def car(name):
while True:
if event.is_set():
print("%s is running...."%name)
time.sleep(1)
else:
print("%s is waiting...."%name)
event.wait()
car_1 = threading.Thread(target=car,args=("凯迪拉克",))
car_1.start()
light = threading.Thread(target=lighter,)
light.start()
7.Queue(队列):
[ 1.解耦(合) 2.提高效率 ] [ 例如:老师说可以拿硬盘考“视频”了,一伙人冲上来,很乱,而且中间靠后的人有可能要等30多分钟 (效率拉崩);而且你必须得等到“老师”给你拷完;你可以把你的硬盘disk,放在桌子(队列)上,等10-20分钟以后,再过来拿,你中间的时间去干别的事去,效率拉满;而且你把你得硬盘放在桌子上,老师可以自由的安排其他同学帮你copy视频,你和老师之间的“耦合关系”解除]
q =queue.Queue(maxsize=0)#先进先出
q = queue.LifoQueue(maxsize=0)#后进先出
q = queue.PriorityQueue(maxsize = 0)#优先级进出
import queue
q =queue.Queue(maxsize=0)#先进先出
q.put(1)
q.put(2)
q.put(3)
print(q.qsize())
print(q.get())
print(q.get())
print(q.get())#只能去3次,你就存了三个数...
存了多少,你取多少…你再get第四次的时候,就会卡死…
print(q.get_nowait())#第4次的时候,换成get_nowit
get_nowit,这个在你取不到的时候,会报错…
print(q.get(block=False ,timeout=1))#第4次的时候,换成 block = flase(不阻塞) timeout =1(卡一秒,然后报错)
import queue
q =queue.PriorityQueue()
q.put((12,"蔡徐坤"))
q.put((1,"蔡徐坤2代"))
q.put((9,"蔡徐坤3代"))
q.put((0,"蔡徐坤好多代"))
q.put((15,"蔡徐坤代王"))
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.get())
按序数大小的优先关系
生产者和消费者模型:
import queue,time,threading
q = queue.Queue(maxsize=10)
def product():
count =1
while True:
print("买了第%s个篮球"%count)
q.put(count)
count +=1
time.sleep(1)
def man(name):
while True:
print("%s 打爆了 第%s个篮球"%(name,q.get()))
time.sleep(1.5)
producter = threading.Thread(target=product,)
producter.start()
man1 = threading.Thread(target=man,args=("蔡徐坤",))
man2 = threading.Thread(target=man,args=("蔡徐坤2代",))
man1.start()
man2.start()