【python自动化第九篇:进程,线程,协程】

简要:

  1. paramiko模块
  2. 进程与线程
  3. python GIL全局解释器锁

一、PARAMIKO模块

 

  • 实现远程ssh执行命令

import paramiko

ssh = paramiko.SSHClient()  # 创建ssh对象
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 开始连接服务器
ssh.connect(hostname='192.168.1.102', port=22, username='wanghui', password='123456')
stdin, stdout, stderr = ssh.exec_command('df')  # 执行命令
# resault = stdout.read() #收集命令执行结果
# print(resault.decode())
# 三元运算实现
res, err = stdout.read(), stderr.read()
resault = res if res else err
print(resault.decode())
ssh.close()  # 关闭连接

远程传输文件 

import paramiko
transport = paramiko.Transport(('10.70.18.2',22)) #创建传输对象
transport.connect(username='root',password='abc/123')   #登录认证
sftp = paramiko.SFTPClient.from_transport(transport) #创建sftp对象
sftp.put('test','/opt/ssh_transe.txt') #上传文件到/opt下,存放名称改为ssh_transe.py
sftp.get('/opt/ssh_transe.txt','test2') #下载文件到当前目录下并改名为test2
transport.close() #关闭连接

使用密钥ssh链接远程机执行命令 

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa') #创建私钥对象,指定私钥文件
ssh = paramiko.SSHClient() #实例化ssh
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #自动添加到对方的know_hosts文件
#使用私钥链接机器
ssh.connect(hostname='10.70.18.2',port=22,username='root',pkey=private_key)
#执行第一条命令
stdin,stdout,stderr = ssh.exec_command('ls /opt')
resault = stdout.read()
print(resault.decode())
stdin,stdout,stderr = ssh.exec_command('df')#执行第二条命令
resault1 = stdout.read()
print(resault1.decode())
ssh.close()

使用密钥sftp收发文件

1

2

3

4

5

6

7

8

9

10

#!/usr/bin/env python

# -*- coding:utf-8 -*-

#Author:wanghui

import paramiko

private_key=paramiko.RSAKey.from_private_key_file('id_rsa')   #创建私钥对象,指定私钥文件

transport = paramiko.Transport(('10.70.18.2',22))             #创建传输对象

transport.connect(username='root',pkey=private_key)           #指定用户和私钥连接

sftp= paramiko.SFTPClient.from_transport(transport)           #创建sftp实例

#sftp.put('test2','/opt/ssss')                                #上传文件

sftp.get('/opt/ssss','message.txt')                           #下载文件

二、进程&线程简单的多线程栗子:

    一般模式:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import threading,time

 

def run(n):

    print('task ',n)

    time.sleep(2)

#多线程执行:并行执行

t1 = threading.Thread(target=run,args=('t1',))    #定义线程

t1.start()                                         #启动线程

t2 = threading.Thread(target=run,args=('t2',))

t2.start()

#单线程执行:

run('t1')            #直接运行函数

run('t2')

      函数形式:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import threading,time

 

class Mythread(threading.Thread):                #继承threading.Thread

    def __init__(self,n):                        #初始化

        super(Mythread,self).__init__()            #重构

        self.n = n                                #实例化参数n

    def run(self):                               #定义run函数

        print('running task',self.n)

 

t1 = Mythread('t1')

t2 = Mythread('t2')

 

t1.start()

t2.start()

 还有俩关于线程的参数:threading.current_thread(),threading.active_count()) 当前线程,线程个数 

守护线程:非守护线程退出了,也就退出了,二守护线程也就不再那么重要了,

守护进程就是要守护其他进程,主线程没法被设置成守护线程的

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

#!/usr/bin/env python

# -*- coding:utf-8 -*-

#Author:wanghui

import threading,time

def run(n):                     #定义函数

    print('running task',n)

    time.sleep(2)

    print('task down',n)

 

start_time = time.time()      #定义开始时间

t_objs = []                   #存线程实例

for in range(50):           #定义50个并发执行的线程

    = threading.Thread(target=run,args=('thread:%s'%i,))    #实例化线程

    t.setDaemon(True)                                         # 设置当前线程设置为守护线程,一定要在start之前

    t.start()                            #启动线程

    t_objs.append(t)                     #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里

 

 

cost_time = time.time() - start_time    #定义结束时间

print("all threads has finished...",threading.current_thread(),threading.active_count())               #打印当前线程,线程个数

print("cost time ",cost_time)

    全局解释器锁GIL:python的线程是调用操作系统原生的线程,python要调用C语言线程的时候,要注意到上下文的切换关系(在python中同一时间,执行的线程只有一个,而不像是所谓的多核多处理那样)

      线程锁(Mutex):也就是互斥锁

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import threading,time

def run(n):                      #定义函数

    lock.acquire()               #获取一把锁

    global num

    num += 1

    time.sleep(1)                #这话时候锁没有释放,需要等待释放才能接受下一个线程

    lock.release()               #释放锁

lock = threading.Lock()          #定义锁实例

num = 0                          #定义全局变量

t_objs = []                      #存线程实例

for in range(50):              #定义50个并发执行的线程

    = threading.Thread(target=run,args=('thread:%s'%i,))    #实例化线程

    t.start()                                                 #启动线程

    t_objs.append(t)                                          #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里

 

for in t_objs:                                              #循环线程实例,等待所有线程执行完毕

     t.join()

 

print("all threads has finished...")

print('num:',num)

  递归锁RLock问题:

复制代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
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,然后执行run1,run2.最后释放
    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(10):
    t = threading.Thread(target=run3)
    t.start()

while threading.active_count() != 1:        #当前线程不等于1那就继续打印结果
    print(threading.active_count())
else:
    print('----all threads done---')
    print(num, num2)

复制代码

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

复制代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:wanghui
import threading,time
def run(n):
    semaphore.acquire()       #获取信号量
    time.sleep(1)
    print("run the thread:%s\n" %n)
    semaphore.release()          #释放信号量

num = 0                          #定义全局变量
semaphore = threading.BoundedSemaphore(5)     #实例化信号量,最多允许5个线程并行
for i in range(40):
    t = threading.Thread(target=run,args=(i,))    #并行40个线程
    t.start()     #启动线程

while threading.active_count() != 1:
    print(threading.active_count())
else:
    print("all threads done...")
    print(num)

复制代码

 三、事件(Event)

python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。

事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

以下是个红绿灯的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

#!/usr/bin/env python

# -*- coding:utf-8 -*-

#Author:wanghui

import threading,time

event = threading.Event()

 

def lighter():

    count = 0       #设置状态位

    event.set()     #设置为通行状态,也就是绿灯

    while True:

        if count > 3 and count < 6:

            event.clear()            #这会儿变成红灯

            print('\033[41;1mred light is on...\033[0m')

        elif count > 6:

            event.set()        #变成绿灯

            count=0            #标志位清空

        else:

            print('\033[42;1mgreen lignt is on\033[0m')

        time.sleep(1)

        count += 1

def car(name):

    while True:

        if event.is_set():          #表示为绿灯

            print('%s running..'%name)

            time.sleep(1)

        else:

            print("%s now red light is on ,stop")

            event.wait()

            print('green light is on ,go %s!!'%name)

car1 = threading.Thread(target=car,args=('Moto',))

car1.start()

light = threading.Thread(target=lighter,)

light.start()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值