day 30
day 30 GIL、死锁现象、信号量、线程队列
01.GIL全局解释器锁(基于Cpython)
- GIL本质是一个互斥锁
- 为了阻止同一进程内多线程同时执行(并行)
- 单个进程下无法实现多线程并行,只能实现并发
- 在线程处于非阻塞态时,GIL保证了线程对解释器的使用权为串行,遇到线程进入阻塞态时释放它(同时保证其不被垃圾回收机制回收),接收下一个线程进行运行
- 多线程作用;
- 在IO密集型的情况下使用多线程可以节省内存和时间(多进程遇到大量的IO操作进入阻塞态,也会变成 保存状态+切换 和多线程的并发相同,还要浪费时间去开辟内存空间)
- 在计算密集型的程序中使用多进程并行可以节省很多运算时间(有几个核心就有几个进程同时运行)
02.死锁现象
-
加锁与释放锁分别放在两个线程当中,a的钥匙锁在b里,b的钥匙锁在a里
-
导致锁解不开,下一个线程就无法抢到该锁,导致程序一致处于等待状态
-
递归锁RLock;用于解决死锁问题
-
一把锁可以提供给多个线程去使用,在一个线程内可以上多重该锁
-
mutex = Rlock() # 创建一个递归锁,用法与互斥锁相同
-
递归锁必须要在被释放之后才能再次绑定给另一个线程
-
03.信号量
-
Semaphore管理这一个内置的计数器
-
是可以被多个人同时使用的锁,其特点为,
-
from threading import current_thread import time sm = Semaphore(5) # 创建一个信号量,也是一种锁,规定同时可以有5个人使用该锁(相当于有5把锁)默认为1 def func(): sm.acquire() print(current_thread().name) time.sleep(1) sm.release() for line in range(20): t = Thread(target=func) t.start()
04.线程队列
-
FIFO先进先出队列(普通队列)
-
LIFO后进先出队列
-
优先级队列priorityQueue;
- 数值越小优先级越高
- 若传入元组以传入的第一个参数(必须是数字或字符串;会根据编码将其转换为数字)为准
- 第一个优先级相同再比对下一个参数,同位置参数的数据类型需相同
- 若优先级完全相同,按照先进先出规则取值
-
# 创建队列需导入内置的queue模块 import queue q1=queue.Queue() # 创建一个普通队列,先进先出 q2=queue.LifoQueue() # 创建一个后进先出队列 q3=queue.PriorityQueue() # 创建一个优先级队列