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

简要:

paramiko模块

进程与线程

python GIL全局解释器锁

一、PARAMIKO模块

实现远程ssh执行命令

#!/usr/bin/env python

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

#Author:wanghui

import paramiko

ssh = paramiko.SSHClient() #创建ssh对象

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #允许连接不在know_hosts文件中的主机

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() #关闭连接

远程传输文件

#!/usr/bin/env python

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

#Author:wanghui

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链接远程机执行命令

#!/usr/bin/env python

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

#Author:wanghui

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收发文件

#!/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') #下载文件

二、进程&线程

线程:

操作系统能够尽心运算调度的最小单位,他被包含在进程当中,是进程中的实际运作单位;

一条线程指的是进程中的单一顺序的控制流,一个进程可以并发多个线程,每个进程并行执行多个线程;

线程就是cpu执行时所需要的一段执行的上下文;

子线程又可以创建子线程;

启动线程的速度要大于进程

进程:

要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用、内存的管理、网络接口的调用等;

对各种资源管理的集合就可以成为进程;

进程要操作cpu必须要先创建一个线程;

进程和线程的区别:

线程共享内存空间,进程是独立的内存空间;

同一个进程的线程之间可以直接互相访问,连个进程要想通信,必须要经过一个中间代理来实现;

新的线程容易创建,新的进程需要克隆他的父进程;

一个线程可以控制和操作同一进程里的其他线程;

对于主线程的修改会影响到其他线程的运行(数据共享);对于一个父进程的修改,不会影响子进程(数据不共享)

简单的多线程栗子:

一般模式:

#!/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')

函数形式:

#!/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()

多线程执行时间讨论(join)

#!/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 i in range(50): #定义50个并发执行的线程

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

t.start() #启动线程

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

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

t.join()

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

print("cost time ",cost_time)

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

#!/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 i in range(50): #定义50个并发执行的线程

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

t.start() #启动线程

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

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

# t.join()

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

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

print("cost time ",cost_time)

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

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

#!/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 i in range(50): #定义50个并发执行的线程

t = 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):也就是互斥锁

#!/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 i in range(50): #定义50个并发执行的线程

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

t.start() #启动线程

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

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

t.join()

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

print('num:',num)

递归锁RLock问题:

#!/usr/bin/env python#-*- coding:utf-8 -*-#Author:wanghui

importthreading, time###定义三个函数

defrun1():print("grab the first part data")

lock.acquire()globalnum

num+= 1lock.release()returnnumdefrun2():print("grab the second part data")

lock.acquire()globalnum2

num2+= 1lock.release()returnnum2def 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)

View Code

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

#!/usr/bin/env python#-*- coding:utf-8 -*-#Author:wanghui

importthreading,timedefrun(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)

View Code

三、事件(Event)

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

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

以下是个红绿灯的例子:

#!/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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值