锁
Lock(线程锁)(互斥锁)
from threading import Thread x=0 def foo(): global x for i in range(10000000): if i%1000 ==0: print(x) x+=1 t_l = [] for i in range(2): t = Thread(target=foo) t.start() t_l.append(t) for i in t_l: i.join() print(x)
对可能发生数据安全的地方进行上锁
上锁外的地方还是并发的,
但上锁的代码就变成了串行
保证了数据安全
死锁
from threading import Thread,Lock, current_thread import time lo = Lock() lc = Lock() def func1(): lo.acquire() print(current_thread().name, "抢到了锁1") lc.acquire() print(current_thread().name, "抢到了锁2") lc.release() print(current_thread().name, "释放了锁2") lo.release() print(current_thread().name, "释放了锁1") def func2(): lc.acquire() print(current_thread().name, "抢到了锁2") time.sleep(0.1) lo.acquire() print(current_thread().name, "抢到了锁1") lo.release() print(current_thread().name, "释放了锁1") lc.release() print(current_thread().name, "释放了锁2") def run(): func1() func2() for i in range(10): t = Thread(target=run) t.start()
指两个或两个以上的线程在执行过程中
由于竞争资源或者由于彼此通信而造成的一种阻塞的现象
若无外力作用,它们都将无法继续执行下去
即:线程手里互相有其它线程要执行下去的必备资源
RLock(递归锁)
import time from threading import Thread, RLock, current_thread rl = RLock() def func1(): rl.acquire() print(current_thread().name, "抢到了锁+1") rl.acquire() print(current_thread().name, "抢到了锁+1") rl.release() print(current_thread().name, "释放了锁-1") rl.release() print(current_thread().name, "释放了锁-2") def func2(): rl.acquire() print(current_thread().name, "抢到了锁+1") time.sleep(0.1) rl.acquire() print(current_thread().name, "抢到了锁+2") rl.release() print(current_thread().name, "释放了锁-1") rl.release() print(current_thread().name, "释放了锁-2") def run(): func1() func2() for i in range(10): t = Thread(target=run) t.start()
同一把递归锁可以在同一线程中被多次acquire()
但是acquire()几次就要释放release()几次
PS: 这把递归锁当被某一线程申请到了
其他线程就无法acquire()了
GIL(全局解释器锁)
在Cpython解释器中有一把GIL锁(全局解释器锁),
GIl锁本质是一把互斥锁。
线程抢的是GIL锁,GIL锁相当于执行权限
导致了同一个进程下,同一时间只能运行一个线程,无法利用多核优势
为什要有GIL锁?
- 因为cpython自带的垃圾回收机制不是线程安全的,所以要有GIL锁
Semaphore(信号量)
from threading import Thread,Semaphore,current_thread import time se = Semaphore(3) def run(): se.acquire() print(current_thread().name,"抢到了锁") time.sleep(0.5) se.release() for i in range(100): t = Thread(target=run) t.start()
设置互斥锁的数量Semaphore(n)
本质上,当信号量的值为1时 就是互斥锁
同一时刻这把锁可以被申请n次
进程锁
from multiprocessing import Process, Lock import json,time def run(lock): lock.acquire() with open("a.json",'r',) as f: res = json.load(f) print(res) time.sleep(2) with open('a.json','w') as fw: res['count'] -= 1 json.dump(res,fw) lock.release() if __name__ == '__main__': """解决方案""" lock = Lock() # 在这里加一把锁,切记是只有一把锁 p_l = [] for i in range(10): p = Process(target=run,args=(lock,)) p_l.append(p) p.start() for p in p_l: p.join() with open('a.json','r') as f: print(json.load(f))
from multiprocessing import Lock
- 导入Lock
lock = Lock()
- 定义锁对象
lock.acquire()
- 为你的某一部分代码上锁
- 注意的是,当这把锁上锁时,其他进程无法运行这部分的代码
lock.release()
- 解锁
- 只有解锁后,其他进程才可以抢到这把锁来继续运行自己的代码
注意:在多进程是要确保多个进程使用的是同一把锁
XMind: ZEN - Trial Version