python 线程锁
为什么会有锁?
在编程世界中,只要语言设计到多线程的,都会有线程安全(线程安全请移步这里)的说法,而在所有支持多线程的语言中,锁的大多用法都是为了线程安全。
在python中锁的左右有这两种:
1. 维护线程安全
2. 为了能够连续执行线程中的某一段连续的代码
python中的5种锁的编写和区别:
同步锁:Lock(一次执行一个线程)
线程安全时,多线程操作时,内部会让所有的线程排队处理。
线程不安全 + 锁 => 排队处理
python的使用列表,字典,Queue的容器都是线程安全的
import threading import time lst = [] lock = threading.Lock() def func(arg): lock.acquire() #加锁 lst.append(arg) time.sleep(0.01) print(arg, lst[-1]) lock.release() #解锁 for i in range(10): t = threading.Thread(target=func, args=(i,)) t.start()
在线程种加锁时,只有当前线程的锁解开才能执行下一个线程。
递归锁:RLock(一次释放一个线程进入锁)
import threading import time lst = [] lock = threading.RLock() def func(arg): lock.acquire() #加锁 lock.acquire() #第二次加锁 lst.append(arg) time.sleep(0.01) m = lst[-1] print(arg, m) lock.release() #解锁 lock.release() #第二次解锁 for i in range(10): t = threading.Thread(target=func, args=(i, )) t.start()
递归锁使用方法跟同步锁大致一样,唯一的区别是能够在线程中进行多次加锁和解锁,这个在同步锁中是无法做到的(会出现死锁),所以我们需要用到加锁是大多都是使用RLock
信号量:BoundedSemaphore (一次释放N个线程进入锁)
import threading import time lock = threading.BoundedSemaphore(3) #每次放行3个线程执行 def func(arg): lock.acquire() print(arg) time.sleep(1) lock.release() for i in range(10): t = threading.Thread(target=func, args=(i,)) t.start()
条件:Condition (指定一次释放多少线程进入锁)
import threading lock = threading.Condition() def func(arg): print('线程进来了') lock.acquire() lock.wait() print(arg) lock.release() for i in range(20): t = threading.Thread(target=func, args=(i,)) t.start() while True: inp = int(input('>>>')) lock.acquire() lock.notify(inp) lock.release()
事件:Event(一次释放所有线程进入锁,红绿灯原理)
import threading lock = threading.Event() lock2 = threading.RLock() def func(arg): print('线程进来了',arg) lock.wait() #加锁 红灯 print(arg) for i in range(10): t = threading.Thread(target=func, args=(i,)) t.start() tmp1 = input('解锁1:') lock.set() #全部解锁 绿灯 lock.clear() # 重置锁状态 def func2(arg): print('线程进来了',arg) lock.wait() #加锁 红灯 print(arg) for i in range(10): t = threading.Thread(target=func, args=(i,)) t.start() tmp2 = input('解锁2:') lock.set() #全部解锁 绿灯