鎖-互斥鎖,死鎖
阿新 • • 發佈:2022-04-18
1.互斥鎖
當多個執行緒幾乎同時修改某一個共享資料的時候,需要進行同步控制
執行緒同步能夠保證多個執行緒安全訪問競爭資源,最簡單的同步機制是引入互斥鎖。
互斥鎖為資源引入一個狀態:鎖定/非鎖定
某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為“鎖定”,其他執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成“非鎖定”,其他的執行緒才能再次鎖定該資源。
互斥鎖保證了每次只有一個執行緒進行寫入操作,從而保證了多執行緒情況下資料的正確性
1.1 互斥鎖
threading模組中定義了Lock類,可以方便的處理鎖定:
# 建立鎖
mutex = threading.Lock()
# 鎖定
mutex.acquire()
# 釋放
mutex.release()
1.2 注意
如果這個鎖之前是沒有上鎖的,那麼acquire不會堵塞
如果在呼叫acquire對這個鎖上鎖之前 它已經被 其他執行緒上了鎖,那麼此時acquire會堵塞,直到這個鎖被解鎖為止
1.3 上鎖解鎖過程:
當一個執行緒呼叫鎖的acquire()方法獲得鎖時,鎖就進入“locked”狀態。 每次只有一個執行緒可以獲得鎖。如果此時另一個執行緒試圖獲得這個鎖,該執行緒就會變為“blocked”狀態,稱為“阻塞”,
直到擁有鎖的執行緒呼叫鎖的release()方法釋放鎖之後,鎖進入“unlocked”狀態。 執行緒排程程式從處於同步阻塞狀態的執行緒中選擇一個來獲得鎖,並使得該執行緒進入執行(running)狀態。
1.4 存在的問題
鎖的好處:
確保了某段關鍵程式碼只能由一個執行緒從頭到尾完整地執行
鎖的壞處:
阻止了多執行緒併發執行,包含鎖的某段程式碼實際上只能以單執行緒模式執行,效率就大大地下降了
由於可以存在多個鎖,不同的執行緒持有不同的鎖,並試圖獲取對方持有的鎖時,可能會造成死鎖
2.死鎖
線上程間共享多個資源的時候,如果兩個執行緒分別佔有一部分資源並且同時等待對方的資源,就會造成死鎖。
儘管死鎖很少發生,但一旦發生就會造成應用的停止響應。
避免死鎖
程式設計時要儘量避免(銀行家演算法)
新增超時時間等