python_day9_paramiko模块 / ssh 密钥 / 进程与线程 / 多线程 / 主线程与子线程 / 线程锁、信号量 / Event / Queue

python_paramiko模块 / ssh 密钥 / 进程与线程 / 多线程 / 主线程与子线程 / 线程锁、信号量 / Event / Queue

在这里得感谢,老师Alex金角大王(路飞学城IT)
Python(给兄弟们挂个🔗)

银角大王,博客

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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值