多线程理论———— threading
什么是线程
线程也是一种多任务编程方法,可以利用计算机多核资源完成程序的并发执行。线程又被称为轻量级的进程。
线程的特征
* 线程是计算机多核分配的最小单位
* 一个进程可以包含多个线程
* 线程也是一个运行的过程,消耗计算机资源,多个线程共享进程的资源和空间
* 线程的创建删除消耗的资源都要远远小于进程消耗的资源
* 多个线程之间执行互不干扰
* 线程也有自己的特有属性,比如指令集,ID
threading.Thread()
功能:创建线程对象
参数:name 线程名称 默认 Thread-1
target 线程函数
args 元组 给线程函数位置传参
kwargs 字典 给线程函数键值传参
返回值:线程对象 t
t.start() 启动线程 自动运行线程函数
t.join([timeout]) 回收线程
线程对象属性
t.is_alive() 查看线程状态
t.name 线程名称
t.setName() 设置线程名称
t.getName() 获取线程名称
threading.currentThread() 获取当前线程对象
t.daemon 属性
默认情况主线程退出不会影响分支线程执行
如果设置为True 则分支线程随主线程退出
设置方法 :
t.daemon = True
t.setDaemon(True)
判断属性值 t.isDaemon()
* 要在start前设置,不能与join同用
创造自己的线程类
步骤:
1 继承 Thread
2 加载 Thread上的 __init__
3 重写run方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from threading import Thread from time import ctime,sleep import threading def platy(song,sec): for i in range(2): print('Playting %s:%s,%s'%(song,ctime(),threading.currentThread().getName())) sleep(sec) class MYThread(Thread): def __init__(self,target,args=(),kwargs=None): #1 super().__init__(target=target,args=args,kwargs=kwargs) super().__init__() self.target=target self.args=args self.kwargs=kwargs def run(self): self.target(*self.args,**self.kwargs) #1 super().run() t = MYThread(target=platy,args=('交浅',),kwargs={'sec':2}) t.start()
线程通信
通信方法 :多个线程共享进程的空间,所以线程间通信使用全局变量完成。
注意事项: 线程间使用全局变量往往要同步互斥机制保证通信安全
线程同步互拆方法
线程的event
e = threading.Event() 创建事件对象
e.wait([timeout]) 如果e 为设置状态则不阻塞否则阻塞
e.set() 将e变为设置状态
e.clear() 清除设置
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import threading from time import sleep s=None e = threading.Event() def bar(): print('bar山头') e.wait() global s s= '天王盖地虚' def foo(): print('进出口令就是自己人') sleep(2) if s=='天王盖地虚': print('自己人') else: print('打死他') e.set() def fun(): sleep(1) global s s= '小允' t1 =threading.Thread(target=bar) t1.start() t2 = threading.Thread(target=foo) t2.start() fun() e.set() t1.join() t2.join()
线程锁
lock = threading.Lock() 创建锁对象
lock.acquire() 上锁
lock.release() 解锁
* 也可以通过with 上锁,上锁状态调用aquire会阻塞
python 线程的GIL问题(全局解释器锁)
python ---> 支持多线程 ---> 同步互斥 ---> 加锁 ---> 超级锁,给解释器加锁 ---> 解释器同一时刻只能解释一个线程
后果:
一个解释器同一时刻只能解释执行一个线程,所以导致python 线程效率低下。但是当遇到IO 阻塞时线程会主动让出解释器,因此python 线程更加适合高延迟的IO 程序并发
解决方法:
* 尽量用进程完成并发
* 不适用C 解释器
* 尽量使用多种方案组合的方式进行并发操作,线程用作高延迟IO
不是所有的成功都是坐享其成,联系作者v(13147256756)