今日内容 1,GIL全局解释器锁 2,死锁 3,信号量 4,event事件 5,队列一:GIL全局解释器锁 什么是GIL 全局解释器锁: 它的本质也是一把互斥锁,是在CPython解释器锁,将并发变为串行的, 牺牲效率,保证数据安全性! 作用:用来阻止同一个进程下的多个线程的同时执行 (同一个进程内多个线程无法实现并行但是可以实现并发) GIL的存在是因为CPython解释器的内存管理不是线程安全的 研究python的多线程是否有用需要分情况讨论 四个任务 计算密集型的 10s 单核情况下 开线程更省资源 多核情况下 开进程 10s 开线程 40s 四个任务 IO密集型的 单核情况下 开线程更节省资源 多核情况下 开线程更节省资 2 死锁: from threading import Thread,Lock,current_thread,RLock import time # RLock 递归锁 # Rlock可以被第一个抢到锁的人连续的acquire和release #每acquire一次锁身上的计数加1 #每release一次锁身上的计数减1 #只要锁的计数不为0 其他人都不能抢 mutexA = Lock() mutexB = Lock() #mutexA = mutexB = RLock() # A B现在是同一把锁 class MyThread(Thread): def run(self): # 创建线程自动触发run方法 run方法内调用func1 func2相当于也是自动触发 self.func1() self.func2() def func1(self): mutexA.acquire() print('%s抢到了A锁'%self.name) # self.name等价于current_thread().name mutexB.acquire() print('%s抢到了B锁'%self.name) mutexB.release() print('%s释放了B锁'%self.name) mutexA.release() print('%s释放了A锁'%self.name) def func2(self): mutexB.acquire() print('%s抢到了B锁'%self.name) time.sleep(1) mutexA.acquire() print('%s抢到了A锁' % self.name) mutexA.release() print('%s释放了A锁' % self.name) mutexB.release() print('%s释放了B锁' % self.name) for i in range(10): t = MyThread() t.start() 3,信号量 (Semaphore) # 信号量可能在不同的领域中 对应不同的知识点 互斥锁:一个厕所(一个坑位) 信号量:公共厕所(多个坑位) from threading import Semaphore,Thread import time import random # 同时有四十个线程来抢五个坑位,即有五个线程抢到五个坑位,同时执行五个线程 五个人同时抢到锁,同时释放锁 sm = Semaphore(5) # 造了一个含有五个的坑位的公共厕所 def task(name): sm.acquire() print('%s占了一个坑位'%name) time.sleep(random.randint(1,3)) 抢到锁睡得时间不一样 sm.release() for i in range(40): t = Thread(target=task,args=(i,)) t.start() 4,event事件 一个子进程等待另一个子进程接受再走,或者一个子线程等待另一个子线程结束再走 即 子等子时,就用event事件,子执行完毕给另一个子发信号,另一个子只要等待到信号,就开始立即执行 案列: 红灯与车 (灯一个,车多个,即给车多个线程) from threading import Event,Thread import time # 先生成一个event对象******** e = Event() def light(): print('红灯正亮着') time.sleep(3) e.set() # 发信号********** print('绿灯亮了') def car(name): print('%s正在等红灯'%name) e.wait() # 等待信号********** print('%s加油门飙车了'%name) t = Thread(target=light) t.start() for i in range(10): t = Thread(target=car,args=('伞兵%s'%i,)) t.start() 5,队列(多线程优先用队列,而不是加锁) 同一个进程下的多个线程本来就是数据共享 为什么还要用队列 因为队列是管道+锁 使用队列你就不需要自己手动操作锁的问题 因为锁操作的不好极容易产生死锁现象 import queue q = queue.Queue() # 普通队列,产生一个队列对象 q.put('hahha') print(q.get()) q = queue.LifoQueue() #后进先出队列,==》堆栈 q.put(1) q.put(2) q.put(3) print(q.get()) q = queue.PriorityQueue() #优先级队列,支持你给你放的数据设置优先级, 取的时候,数字越小 优先级越高*********** q.put((10,'haha')) q.put((100,'hehehe')) q.put((0,'xxxx')) q.put((-10,'yyyy')) print(q.get())
转载于:https://www.cnblogs.com/Fzhiyuan/p/11353667.html
相关资源:JAVA上百实例源码以及开源项目