day 30

day 30 GIL、死锁现象、信号量、线程队列

01.GIL全局解释器锁(基于Cpython)

  1. GIL本质是一个互斥锁
  2. 为了阻止同一进程内多线程同时执行(并行)
    1. 单个进程下无法实现多线程并行,只能实现并发
  3. 在线程处于非阻塞态时,GIL保证了线程对解释器的使用权为串行,遇到线程进入阻塞态时释放它(同时保证其不被垃圾回收机制回收),接收下一个线程进行运行
  4. 多线程作用;
    1. 在IO密集型的情况下使用多线程可以节省内存和时间(多进程遇到大量的IO操作进入阻塞态,也会变成 保存状态+切换 和多线程的并发相同,还要浪费时间去开辟内存空间)
    2. 在计算密集型的程序中使用多进程并行可以节省很多运算时间(有几个核心就有几个进程同时运行)

02.死锁现象

  1. 加锁与释放锁分别放在两个线程当中,a的钥匙锁在b里,b的钥匙锁在a里

  2. 导致锁解不开,下一个线程就无法抢到该锁,导致程序一致处于等待状态

  3. 递归锁RLock;用于解决死锁问题

    1. 一把锁可以提供给多个线程去使用,在一个线程内可以上多重该锁

    2. mutex = Rlock() # 创建一个递归锁,用法与互斥锁相同
      
    3. 递归锁必须要在被释放之后才能再次绑定给另一个线程

03.信号量

  1. Semaphore管理这一个内置的计数器

  2. 是可以被多个人同时使用的锁,其特点为,

  3. 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.线程队列

  1. FIFO先进先出队列(普通队列)

  2. LIFO后进先出队列

  3. 优先级队列priorityQueue;

    1. 数值越小优先级越高
    2. 若传入元组以传入的第一个参数(必须是数字或字符串;会根据编码将其转换为数字)为准
    3. 第一个优先级相同再比对下一个参数,同位置参数的数据类型需相同
    4. 若优先级完全相同,按照先进先出规则取值
  4. # 创建队列需导入内置的queue模块
    import queue
    q1=queue.Queue() # 创建一个普通队列,先进先出
    q2=queue.LifoQueue() # 创建一个后进先出队列
    q3=queue.PriorityQueue() # 创建一个优先级队列
    
原文地址:https://www.cnblogs.com/luocongyu/p/11728474.html