當多個執行緒幾乎同時修改某乙個共享資料的時候,需要進行同步控制。同步就是協同步調,按預定的先後次序進行執行。執行緒同步能夠保證多個執行緒安全訪問競爭資源,最簡單的同步機制是引入互斥鎖。
互斥鎖某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為「鎖定」,其他執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成「非鎖定」,其他的執行緒才能再次鎖定該資源。互斥鎖保證了每次只有乙個執行緒進行寫入操作,從而保證了多執行緒情況下資料的正確性。
threading模組中定義了lock類,可以方便的處理鎖定:
建立鎖
mutex = threading.lock()
# 鎖定
mutex.acquire()
# 釋放
mutex.release()
注意:
如果這個鎖之前是沒有上鎖的,那麼acquire不會堵塞
如果在呼叫acquire對這個鎖上鎖之前 它已經被 其他執行緒上了鎖,那麼此時acquire會堵塞,直到這個鎖被解鎖為止。
和檔案操作一樣,lock也可以使用with語句快速的實現開啟和關閉操作。
使用互斥鎖解決一百萬次加減問題
import threading
g_num = 0
def test(n):
global g_num
for x in range(n):
# lock.acquire()
# g_num += x
# g_num -= x
# lock.release()
# 使用with關鍵字可以很方便的完成互斥鎖的acquire和release功能
with lock:
g_num += x
g_num -= x
print(g_num)
if __name__ == '__main__':
lock = threading.lock()
t1 = threading.thread(target=test, args=(1000000,))
t2 = threading.thread(target=test, args=(1000000,))
t1.start()
t2.start()
上鎖過程:
當乙個執行緒呼叫鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。
每次只有乙個執行緒可以獲得鎖。如果此時另乙個執行緒試圖獲得這個鎖,該執行緒就會變為「blocked」狀態,稱為「阻塞」,直到擁有鎖的執行緒呼叫鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。
執行緒排程程式從處於同步阻塞狀態的執行緒中選擇乙個來獲得鎖,並使得該執行緒進入執行(running)狀態。
總結確保了某段關鍵**只能由乙個執行緒從頭到尾完整地執行
1:阻止了多執行緒併發執行,包含鎖的某段**實際上只能以單執行緒模式執行,效率就大大地下降了
2:由於可以存在多個鎖,不同的執行緒持有不同的鎖,並試圖獲取對方持有的鎖時,可能會造成死鎖
執行緒同步與互斥 互斥鎖
在多工作業系統中,同時執行的多個任務可能都需要使用同一種資源。這個過程有點類似於,公司部門裡,我在使用著印表機列印東西的同時 還沒有列印完 別人剛好也在此刻使用印表機列印東西,如果不做任何處理的話,列印出來的東西肯定是錯亂的。下面我們用程式模擬一下這個過程,執行緒一需要列印 hello 執行緒二需要...
執行緒同步與互斥 互斥鎖
在多工作業系統中,同時執行的多個任務可能都需要使用同一種資源。這個過程有點類似於,公司部門裡,我在使用著印表機列印東西的同時 還沒有列印完 別人剛好也在此刻使用印表機列印東西,如果不做任何處理的話,列印出來的東西肯定是錯亂的。下面我們用程式模擬一下這個過程,執行緒一需要列印 hello 執行緒二需要...
執行緒同步與互斥 實現互斥鎖
今天我們來分享一下,執行緒同步與互斥 互斥鎖的實現。多個執行緒同時訪問共享資料時可能會產生衝突,造成程式執行結果不是我們所預期的結果。不產生衝突的多執行緒訪問情況,和截圖如下 產生衝突的多執行緒訪問情況,和截圖如下 注 每執行一次,結果都可能會不同。由於多執行緒訪問共享資料時可能會產生衝突,不能保證...