鎖是為了可能出現的數據不同步或數據不對稱問題的解決方法,如果需要大量的用戶訪問相同數據時,為了數據的一致性和安全。那么就需要加鎖。
概念:
鎖相當於是將用戶訪問需求進行隊列化,即第一個用戶訪問時,后續用戶無法進行相同數據的訪問。直到第一個用戶訪問完成后,由隊列中的第二個用戶繼續訪問。
互斥鎖
特點:
1. 兩種表現形式,with和acquire,release
2. 在用一個線程中,不能連續acquire多次(進程會卡在這),必須要進行release后才能繼續acquire(會報錯,RuntimeError: release unlocked lock)
3. 在操作全局變量和+=,-=,*=,/=這類計算在賦值類,或lis[0]+=1,dic['key']-=1這類時,就會出現數據不一致的問題。
4. 線程multiprocessing和Threading都有鎖(Lock)這個模塊,而且都能達到下面的要求。
from threading import Thread,Lock
a = 1
def func1(lock):
with lock:
for i in range ( 100000 ):
global a
a - = 1
def func2(lock):
with lock:
for i in range ( 100000 ):
global a
a + = 1
lock = Lock()
t1 = Thread(target = func1,args = (lock,))
t2 = Thread(target = func2,args = (lock,))
t1.start()
t2.start()
t1.join()
t2.join()
print (a)
from Threading import Lock lock = Lock() lock.acquire() print ( 1 ) lock.acquire() print ( 2 ) ''' 1 '''
死鎖現象
就像一個餐桌吃飯,桌子上有一把叉子和一份面,只有兩個都拿到的人才能吃面,那么就會出現一個人拿着叉子不松手,一個人端着面不松手。這樣就僵在那了。導致的死鎖現象。
特點:
1. 一個線程中,存在一把以上的鎖。
2. 多把鎖交替使用。
解決辦法:
1. 使用遞歸鎖(應急使用)
2. 優化代碼(完全解決問題使用)
遞歸鎖
特點:
1. 在同一個線程中,可以連續acquire多次,也不會被鎖住
2. acquire多少次,就需要release多少次。
3. 占用了更多的資源,但是能夠快速解決問題。
4. 遞歸鎖也會發生死鎖現象。
5. 使用方式和互斥鎖一樣。
from threading import Thread,RLock
class SingLeton( object ):
instance = None
rlock = RLock()
def __new__( cls , * args, * * kwargs):
with cls .rlock:
if not cls .instance:
cls .instance = object .__new__( cls )
return cls .instance
for i in range ( 10 ):
print (SingLeton())
