mac2022-06-30  80

Lock(线程锁)(互斥锁)

from threading import Thread x=0 def foo(): global x for i in range(10000000): if i00 ==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

转载于:https://www.cnblogs.com/marklijian/p/11575168.html

最新回复(0)