Python随心记--锁
同步锁 死锁 递归锁 信号量和同步evrnt对象(了解即可) 队列--生产者消费者模型 进程
并发并行与同步异步的概念
并发: ☞系统具有处理多个任务(动作)的能力
并行: ☞系统具有同时处理多个任务(动作)的能力
并行时并发的一个子集
同步:当进程执行到一个IO(等外部的数据)的时候,-------等:就是同步
-------不等:直到数据接收成功,在回来处理
GIL:全局解释锁(无论你启动多少个线程,有多少个cup python在执行的时候会淡定的在同一时刻只允许一个线程在运行)
#因为有GIL,所以同一时刻只有一个线程被CPU执行
任务类型:IO密集型 计算密集型
对IO密集型的任务 pythond的多线程是有意义的
对计算密集型的任务 pythond的多线程是没有意义的(不推荐使用),可采用多进程+协程
同步锁 案列
问题在于加time.sleep(0.001)发生CPU切换 导致结果发生变化
为解决问题前code
import threading import time def sub(): ''' #运行这里时正常的(串型) global num num -= 1 ''' #运行这里会发生异常 global num temp = num time.sleep(1) #@问题在于加time.sleep(0.001)发生CPU切换 导致结果发生变化 num = temp - 1 num = 100 l = [] for i in range(100): t = threading.Thread(target=sub) t.start() l.append(t) for t in l: t.join() print(num)
解决问题后code
import threading import time def sub(): ''' #运行这里时正常的(串型) global num num -= 1 ''' global num lock.acquire() #@枷锁 temp = num time.sleep(0.01) num = temp - 1 lock.release() #释放锁 num = 100 l = [] lock = threading.Lock() #枷锁 for i in range(100): t = threading.Thread(target=sub) t.start() l.append(t) for t in l: t.join() print(num) #这样会引发一个新的问题:可能会出现死锁的情况
死锁 案列code
import threading import time class MyThread(threading.Thread): def actionA(self): A.acquire() #获得一把锁 print(self.name,'gotA',time.ctime()) time.sleep(2) B.acquire() print(self.name, 'gotB', time.ctime()) time.sleep(1) B.release() #释放B锁 A.release() #释放A锁 def actionB(self): B.acquire() # 获得一把锁 print(self.name, 'gotB', time.ctime()) time.sleep(2) A.acquire() print(self.name, 'gotA', time.ctime()) time.sleep(1) A.release() # 释放A锁 B.release() # 释放B锁 def run(self): self.actionA() self.actionB() if __name__ == '__main__': A = threading.Lock() #创建A锁 B = threading.Lock() #创建B锁 L = [] for i in range(5): t = MyThread() t.start() L.append(t) for i in L: i.join() print('ending.........')
解决死锁code:原理相当于:我在用这把锁时候,别人不能在用这把锁
import threading import time class MyThread(threading.Thread): def actionA(self): r_lock.acquire() #获得一把锁 print(self.name,'gotA',time.ctime()) time.sleep(2) r_lock.acquire() print(self.name, 'gotB', time.ctime()) time.sleep(1) r_lock.release() #释放B锁 r_lock.release() #释放A锁 def actionB(self): r_lock.acquire() # 获得一把锁 print(self.name, 'gotB', time.ctime()) time.sleep(2) r_lock.acquire() print(self.name, 'gotA', time.ctime()) time.sleep(1) r_lock.release() # 释放A锁 r_lock.release() # 释放B锁 def run(self): self.actionA() self.actionB() if __name__ == '__main__': # A = threading.Lock() #创建A锁 # B = threading.Lock() #创建B锁 r_lock = threading.RLock() #创建锁对象 L = [] for i in range(5): t = MyThread() t.start() L.append(t) for i in L: i.join() print('ending.........')