一.GIL全局解释器锁
''' 1. 什么是GIL全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程 必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行 但是可以实现并发 在Cpython解释器下,如果想实现并行可以开启多个进程 2. 为何要有GIL 因为Cpython解释器的垃圾回收机制不是线程安全的 3. 如何用GIL 有了GIL,应该如何处理并发 4.总结: 1.io密集型:用多线程(开发中大部分用多线程) 2.计算密集型:用多进程 ''' # from threading import Thread # import time # # def task(name): # print('%s is running' %name) # time.sleep(2) # # if __name__ == '__main__': # t1=Thread(target=task,args=('线程1',)) # t2=Thread(target=task,args=('线程1',)) # t3=Thread(target=task,args=('线程1',)) # t1.start() # t2.start() # t3.start() # 计算密集型:应该使用多进程 # from multiprocessing import Process # from threading import Thread # import os,time # # def work(): # res=0 # for i in range(100000000): # res*=i # # if __name__ == '__main__': # l=[] # print(os.cpu_count()) # start=time.time() # for i in range(6): # # p=Process(target=work) # p=Thread(target=work) # l.append(p) # p.start() # for p in l: # p.join() # stop=time.time() # print('run time is %s' %(stop-start)) #4.271663427352905 # IO密集型: 应该开启多线程 from multiprocessing import Process from threading import Thread import threading import os,time def work(): time.sleep(2) if __name__ == '__main__': l=[] start=time.time() for i in range(300): # p=Process(target=work) #2.225289821624756 p=Thread(target=work) #2.002105951309204 l.append(p) p.start() for p in l: p.join() stop=time.time() print('run time is %s' %(stop-start))
二.GIL vs 自定义互斥锁:
from threading import Thread, Lock import time # n = 100 # muete = Lock() # # # def task(): # global n # with muete: # temp = n # time.sleep(0.1) # n = temp - 1 # # # if __name__ == '__main__': # li=[] # for i in range(100): # t = Thread(target=task) # li.append(t) # t.start() # # for t in li: # t.join() # print(n) # def foo1(): # print("1") # time.sleep(1) # print("睡了一秒") # # def foo2(): # time.sleep(2) # print("222") # # if __name__ == '__main__': # t1=Thread(target=foo1) # t2=Thread(target=foo2) # t1.start() # t2.start() # t1.join() # print("主")
三 .死锁现象与递归锁
""" 死锁现象:指的是互相拿了对方需要的钥匙,但都不放手,导致了程序的堵塞 递归锁:就是为了解决死锁现象:RLock """ from threading import Thread,Lock,RLock import time mutexA=Lock() mutexB=Lock() # mutexB=mutexA=RLock() class Mythead(Thread): def run(self): self.f1() self.f2() def f1(self): mutexA.acquire() print('%s 抢到A锁' %self.name) mutexB.acquire() print('%s 抢到B锁' %self.name) mutexB.release() mutexA.release() def f2(self): mutexB.acquire() print('%s 抢到了B锁' %self.name) time.sleep(2) mutexA.acquire() print('%s 抢到了A锁' %self.name) mutexA.release() mutexB.release() if __name__ == '__main__': for i in range(100): t=Mythead() t.start()
四.信号量
""" 信号量:semaphore 控制统一进程下的并发的线程的个数 """ from threading import Thread, Semaphore import time, random sm = Semaphore(5) def task(name): sm.acquire() print('%s 正在上厕所' % name) time.sleep(random.randint(1, 3)) sm.release() if __name__ == '__main__': for i in range(20): t = Thread(target=task, args=('路人%s' % i,)) t.start()
五.Event 事件
from threading import Thread, Event import time event = Event() def light(): print('红灯正亮着') time.sleep(3) event.set() # 绿灯亮 def car(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=car, args=(i,)) t.start()
六.线程的queue
import queue # queue.Queue() #先进先出 # q=queue.Queue(3) # q.put(1) # q.put(2) # q.put(3) # print(q.get()) # print(q.get()) # print(q.get()) # queue.LifoQueue() #后进先出->堆栈 # q=queue.LifoQueue(3) # q.put(1) # q.put(2) # q.put(3) # print(q.get()) # print(q.get()) # print(q.get()) # queue.PriorityQueue() #优先级 # q=queue.PriorityQueue(3) #优先级,优先级用数字表示,数字越小优先级越高 # q.put((10,'a')) # q.put((-1,'b')) # q.put((100,'c')) # print(q.get()) # print(q.get()) # print(q.get())