python的学习第九天

paramiko模块 生产者消费者 进程线程 GIL LOCK

python的paramiko模块

先写一个用paramiko模块模拟ssh登录服务器执行一个命令:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import paramiko
ssh = paramiko.SSHClient()    #创建SSH对象
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())   #ssh登录的时候的yes /no 添加不在know_hosts文件中的主机
ssh.connect(hostname="192.168.142.129",port=22,username='root',password="centos")
stdin,stdout,stderr = ssh.exec_command("df")  #返回三个值,标准输入 标准输出,错误
result = stdout.read()
print(result.decode("utf-8"))
ssh.close()

模拟ssh 的scp功能 也就是sftp:

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
#模拟ssh的SCP功能
import paramiko
transport = paramiko.Transport(('192.168.142.129',22))  #声明连接的服务器端口和IP
transport.connect(username='root',password="centos")
sftp = paramiko.SFTPClient.from_transport(transport) #把上面声明的传入
sftp.put('aa.txt','/tmp/aa.py') #将本地的文件上传到远程的服务器
sftp.get('/root/c.py','c.py') #将远程的文件下载到本地
transport.close()

 python模拟用秘钥登录执行命令:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa')    #私钥
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='192.168.142.129', port=22, username='root', pkey=private_key)  #用秘钥登录执行命令
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df -h')
# 获取命令结果
result = stdout.read()
print(result.decode())
# 关闭连接
ssh.close()

 scp sftp:

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa')
transport = paramiko.Transport(('192.168.142.129', 22))
transport.connect(username='root', pkey=private_key)
sftp = paramiko.SFTPClient.from_transport(transport)
# 将bb.txt 上传至服务器 /tmp/test.py
sftp.put('/bb.txt', '/tmp/test.py')
# 将bb.txt 下载到本地 local_path
sftp.get('bb.txt', 'cc.py')
transport.close()

 进程和线程

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不独立拥有系统资源,但它可与同属一个进程的其它线程共享该进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个应用程序都至少有一个进程和一个线程。线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的被划分成一块一块的工作,称为多线程。
以上那一段,可以不用看!举个例子,厂家要生产某个产品,在它的生产基地建设了很多厂房,每个厂房内又有多条流水生产线。所有厂房配合将整个产品生产出来,某个厂房内的所有流水线将这个厂房负责的产品部分生产出来。每个厂房拥有自己的材料库,厂房内的生产线共享这些材料。而每一个厂家要实现生产必须拥有至少一个厂房一条生产线。那么这个厂家就是某个应用程序;每个厂房就是一个进程;每条生产线都是一个线程

区别:


a.地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
b.通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
c.调度和切换:线程上下文切换比进程上下文切换要快得多。
d.在多线程OS中,进程不是一个可执行的实体

 一个简单的多线程的例子:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import threading,time
def run(n):
    print("task",n)
    time.sleep(2)
t1 = threading.Thread(target=run,args="t1")
t2 = threading.Thread(target=run,args="t2")
t1.start()
t2.start()
#可以看到就sleep了2秒不是4秒

 类的写法多线程:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
#类的写法
import threading,time
class MyThread(threading.Thread):
    def __init__(self,n):
        super(MyThread,self).__init__()
        self.n = n
    def run(self):
        print("运行 TASK",self.n)
     time.sleep(2) t1
= MyThread("t1") t2 = MyThread("t2") t1.start() t2.start()

 python 线程的Lock普通锁(不可嵌套)RLock普通锁(可嵌套)Semaphore信号量,event 事件

普通锁,也叫互斥锁,是独占的,同一时刻只有一个线程在执行其他的线程都在干等着。

lock 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import time,threading
num = 0
def run(lock):
    global num
    lock.acquire()  # 启动一个锁
    num += 1
    time.sleep(1)
    print(num)
    lock.release()  # 释放一个锁


lock = threading.Lock()  # 实例化
for i in range(4):
    t = threading.Thread(target=run, args=(lock,))  # 记得把锁当作参数传递给func参数
    t.start()
#如果没有锁就会一下全部执行完成,现在看一个一个的执行

threading模块的Lock类,它不支持嵌套锁。RLcok类的用法和Lock一模一样,它支持嵌套,一般直接使用RLcok类

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)


if __name__ == '__main__':

    num, num2 = 0, 0
    lock = threading.RLock()
    for i in range(10):
        t = threading.Thread(target=run3)
        t.start()

while threading.active_count() != 1:
    print(threading.active_count())
else:
    print('----all threads done---')
    print(num, num2)

Semaphore(信号量)

互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

import threading, time
def run(n):
    semaphore.acquire()
    time.sleep(1)
    print("run the thread: %s\n" % n)
    semaphore.release()
if __name__ == '__main__':
    semaphore = threading.BoundedSemaphore(5)  # 最多允许5个线程同时运行
    for i in range(22): #看了好像是5个5个的同时进行,但是是比如5个里面有1个先完成了就会再往里面放一个就是同时5个工作
        t = threading.Thread(target=run, args=(i,))
        t.start()
while threading.active_count() != 1:
    pass  # print threading.active_count()
else:
    print('----all threads done---')

 Event

通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import time,threading
event = threading.Event()  #一个线程事件
#灯和车的事件   event.wait()  event.set()  event.clear() 三种状态
def lighter():  #
    count = 0
    event.set()#
    while True:
        if count >5 and count <10:
            event.clear()  #标志位清空
            print("\033[41;1m 红灯了 ...\033[0m")

        elif count > 10:
            event.set() #设置标志位
            # print("\033[42;1m  绿灯了 ...\033[0m")
            count = 0
        else:
            print("\033[42;1m 绿 灯了 ...\033[0m")
            #count += 1
        time.sleep(1)
        count+=1
def car(name):  #
    while True:
        if event.is_set():  #判断是否有标志位 有就是绿灯 开车中
            print("%s 开车中。。。。(绿的状态)"%name)
            time.sleep(1)
        else:
            print("%s 看到红灯 等待。。。。(红灯状态)"%name)
            event.wait()  #等待标志位设置进行
            print("%s 已经变绿 开始加速开车。。。"%name)
l = threading.Thread(target=lighter)
l.start()
c = threading.Thread(target=car,args=("特斯拉",))
c.start()

 

queue队列

class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #last in fisrt out 
class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列
queue.Queue :先进先出队列 queue.LifoQueue :后进先出队列  queue.PriorityQueue :优先级队列  queue.deque :双向队列
#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import queue
q = queue.Queue(3) #先进先出 LifoQueue 后入先出
q.put(1)
q.put(2)
q.put(3)
# q.put(4) 第四个就死了 等待去出就可以继续放了
print(q.get())
print(q.get())
print(q.get())
# print(q.get()) 空就卡死了 这时候用 get_nowait() 就出现异常不卡死 或者 q.get(timeout=1) 或者 q.get(block=False)

排序 vip 靠前

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import queue
q = queue.PriorityQueue(3)
q.put((10,"aa"))
q.put((6,"vip"))
q.put((8,"bb"))
# q.put(4)  第四个就死了 等待去出就可以继续放了
print(q.get())
print(q.get())
print(q.get())
# print(q.get())  空就卡死了 这时候用 get_nowait() 就出现异常不卡死 或者 q.get(timeout=1) 或者 q.get(block=False)

 生产者和消费者:

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力

例子;tao 是生产骨头的 tom猫和jack老鼠是吃这些骨头的一个生产者和消费者的小例子

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = "tao"
import threading,time,queue
q = queue.Queue(maxsize=5)

def producer(name1):
    count = 1
    while True:
        q.put("骨头 %s" % count)
        print("%s生产了%s骨头"%(name1,count))
        count+=1
        time.sleep(3)  #调整时间生产的骨头多下面消费者吃的就会有变化
def consumer(name):
    while True:
        # while q.qsize() > 0:
        print("%s 取到%s 并且吃了这个骨头" %(name,q.get()))
        time.sleep(1)  #吃的慢和快都有变化

p = threading.Thread(target=producer,args=("tao",))
p1 = threading.Thread(target=consumer,args=("tom",))
p2 = threading.Thread(target=consumer,args=("jack",))
p.start()
p1.start()
p2.start()

posted @ 2016-09-21 23:49  aipython  阅读(99)  评论(0)    收藏  举报