今日内容
1.GIL解释器锁
2.GIL解释器锁与自定义锁
3.死锁现象与递归锁
4.信息量
5.Event
6.线程queue
1.GIL解释器锁
from multiprocessing import Process ''' 因为Cpython解释器中有一个垃圾回收机制,而每个进程下的线程运行代码时,都需要调用该进程内的Cpython解释器代码,同时每一段进程内都会有一个垃圾回收线程, 若Cpython解释器没有这一个GIL锁就会导致线程在运行代码的同时,垃圾回收线程也被同时运行,就会有可能将普通线程产生的一些空间直接当作垃圾被垃圾回收线程 回收,这样就是一种thread safe,所以GIL解释器锁的作用就是为了保证thread safe。 ''' from threading import Thread import time,os def task(): time.sleep(2) # n=0 # for i in range(10000000): # n+=i if __name__ == '__main__': print(os.cpu_count()) l=[] for i in range(8): s = time.time() # p = Process(target=task) t = Thread(target=task) l.append(t) t.start() for i in l: i.join() print(time.time()-s)
2.GIL解释器锁与自定义锁
自定义锁时用来将python代码中的一部分代码从并发变成串行的
from threading import Thread,Lock import time metux = Lock() n = 100 def task(): global n metux.acquire() temp = n time.sleep(0.1) n=temp-1 metux.release() if __name__ == '__main__': l = [] for i in range(100): p = Thread(target=task) l.append(p) p.start() for i in l: i.join() print(n)
3.死锁现象与递归锁
死锁现象
正常的互斥锁,如果被多次使用,是很容易出现死锁现象的,所以应该使用递归锁
from threading import Thread,Lock import time class Mythread(Thread): def run(self): foo1(self.name) foo2(self.name) metuxA = Lock() metuxB = Lock() def foo1(name): metuxA.acquire() print('%s抢到了A锁'%name) metuxB.acquire() print('%s抢到了B锁' % name) metuxB.release() metuxA.release() def foo2(name): metuxB.acquire() print('%s抢到了B锁' % name) time.sleep(2) metuxA.acquire() print('%s抢到了A锁' % name) metuxB.release() metuxA.release() if __name__ == '__main__': for i in range(10): p = Mythread() p.start()
递归锁RLock
递归锁:实在锁上加一个标签如果上一次锁就加一,解锁就减一,直到标签为0才能被别的线程再去使用,否则别的线程一直处于阻塞状态
from threading import Thread,RLock import time class Mythread(Thread): def run(self): foo1(self.name) foo2(self.name) metuxA = RLock() metuxB = RLock() def foo1(name): metuxA.acquire() print('%s抢到了A锁'%name) metuxB.acquire() print('%s抢到了B锁' % name) metuxB.release() metuxA.release() def foo2(name): metuxB.acquire() print('%s抢到了B锁' % name) time.sleep(2) metuxA.acquire() print('%s抢到了A锁' % name) metuxB.release() metuxA.release() if __name__ == '__main__': for i in range(10): p = Mythread() p.start()
4.信息量
from threading import Thread,Semaphore import time,random xh = Semaphore(5) def task(name): xh.acquire() print('%s进入图书馆'%name) time.sleep(random.randint(1,3)) # print('%s离开图书馆' % name) xh.release() if __name__ == '__main__': for i in range(20): q = Thread(target=task,args=('路人%s'%i,)) q.start()
5.Event
from threading import Thread,Event import time event = Event() def light(): print('红灯亮起,无法通行') time.sleep(3) event.set() print('绿灯亮起,车辆通行') def task(name): print('车辆%s,正在等待'%name) event.wait() print('车辆%s,通过'%name) if __name__ == '__main__': t1 = Thread(target=light) t1.start() for i in range(10): t = Thread(target=task,args=(i,)) t.start()
6.线程queue
import queue # q = queue.Queue()#队列 先进先出 # q.put('阿飞') # q.put('大猴子') # q.put('天天笑') # # print(q.get()) # print(q.get()) # print(q.get()) # q = queue.LifoQueue()#堆栈 先进后出 # q.put('阿飞') # q.put('大猴子') # q.put('天天笑') # # print(q.get()) # print(q.get()) # print(q.get()) q = queue.PriorityQueue()#优先级 优先级越高先出(数字越小优先级越高) q.put((1,'阿飞')) q.put((5,'大猴子')) q.put((-6,'天天笑')) print(q.get()) print(q.get()) print(q.get())