锁
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