簡述python多執行緒中的互斥鎖

2021-08-19 16:32:37 字數 3273 閱讀 7560

在程式設計

中,為了

保證共享資料

操作的完整性,引入了

互斥鎖的概念。每個

物件都對應於乙個可稱為" 互斥鎖" 的標記,這個標記用來保證在任一時刻,只能有乙個

執行緒訪問該

物件。在python中由於多執行緒的存在,並且對全域性變數作用時有可能產生全域性變數紊亂問題,所以也加入了同步和互斥等方法,但是我們主要講解互斥鎖:

如下**定義了乙個my_num的全域性變數,而函式sum1和函式sum2都執行對my_num加1操作,並且都執行100萬次+1,在下面的**裡,我們建立了兩個分別執行兩個函式的執行緒,然後呼叫start()啟動執行緒

importthreading

importtime

# 定義全域性變數

my_num = 0

# 迴圈給全域性變數每次加上1

defsum1():

globalmy_num

foriinrange(1000000):

my_num += 1

print("sum1:"

, my_num)

# 迴圈給全域性變數每次加上1

defsum2():

globalmy_num

foriinrange(1000000):

my_num += 1

print("sum2:"

, my_num)

if__name__ == '__main__':

# 建立兩個子執行緒

first_thread = threading.thread(target=sum1)

second_thread = threading.thread(target=sum2)

# 啟動執行緒執行對應的任務

first_thread.start()# 主線程延時1.5秒

# time.sleep(1.5)

# 主線程等待第乙個執行緒執行完成以後,**再繼續往下執行,啟動第二個執行緒執行任務

# first_thread.join() # 執行緒同步: 按照預先定義好的順序乙個任務執行完成另外乙個任務再執行

# print("第乙個執行緒執行完了")

second_thread.start()

得到執行結果如下:

sum1: 1239023

sum2: 1341576

顯然這結果不是我們想要的,我們希望的結果是函式1和函式2都執行100萬次加一,最終結果是想變成200萬,當然,出現這樣的結果,我們也很容易想到原因是:當全域性變數my_num 剛好等於1000(某些數字時,這裡只是假設)的時候,兩個執行緒同時拿到了my_num的值,各自對他進行了+1操作,此時明顯全域性my_num的到的只是加一而不是+2操作(不往細了說)

明顯看出:在乙個程序內非常方便多個執行緒對全域性變數的資料共享,而對全域性變數進行隨意修改可能會造成全域性變數的混亂,即多個執行緒同時對乙個全域性變數操作,會出現資源競爭問題,從而資料結果不正確。

同樣,下面的**中我們加入了互斥鎖

互斥鎖為資源引入乙個狀態:鎖定/非鎖定

某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為「鎖定」,其他執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成「非鎖定」,其他的執行緒才能再次鎖定該資源。互斥鎖保證了每次只有乙個執行緒進行寫入操作,從而保證了多執行緒情況下資料的正確性。

當乙個執行緒呼叫鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。

每次只有乙個執行緒可以獲得鎖。如果此時另乙個執行緒試圖獲得這個鎖,該執行緒就會變為「blocked」狀態,稱為「阻塞」,直到擁有鎖的執行緒呼叫鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。

執行緒排程程式從處於同步阻塞狀態的執行緒中選擇乙個來獲得鎖,並使得該執行緒進入執行(running)狀態。

importthreading

# 定義全域性變數

my_num = 0

# 建立互斥鎖

lock = threading.lock()

# def show():

# print("哈哈")

# # 變數儲存的是函式在記憶體中的位址,儲存的函式引用

# a = show

# a()

# 迴圈給全域性變數每次加上1

defsum1():

# 上鎖

lock.acquire()

globalmy_num

foriinrange(1000000):

my_num += 1

print("sum1:"

, my_num)

# 釋放鎖

lock.release()

# 迴圈給全域性變數每次加上1

defsum2():

# 上鎖

lock.acquire()

globalmy_num

foriinrange(1000000):

my_num += 1

print("sum2:"

, my_num)

# 釋放鎖

lock.release()

if__name__ == '__main__':

# 建立兩個子執行緒

first_thread = threading.thread(target=sum1)

second_thread = threading.thread(target=sum2)

# 啟動執行緒執行對應的任務

first_thread.start()

second_thread.start()

# 互斥鎖:能保證統一時刻只有乙個執行緒執行,那個執行緒搶到這個互斥鎖我們決定不了,但是能保證資料最終不會有問題

可以看到最後的結果,加入互斥鎖後,其結果與預期相符。

得到結果:

sum1: 1000000

sum2: 2000000

鎖的好處:

鎖的壞處:

python執行緒互斥鎖 Python多執行緒與互斥鎖

多執行緒 threading python的thread模組是 較底層的模組,python的threading 模組是對thread做了 些包裝的,可以更加 便的被使 1.使 threading模組 from threading import thread 匯入模組 t thread target ...

多執行緒中的互斥鎖

互斥量mutex 類物件,理解成一把鎖,多個執行緒嘗試用lock 成員函式來對其加鎖,只有乙個執行緒能夠鎖定成功 lock 與unlock 須成對存在,很容易出問題,所以引入 std lock guard 類模板,對於忘記新增unlock 會自動新增,類似於智慧型指標的功能。鎖住的 量多少成為粒度的...

Linux 多執行緒互斥量互斥

同乙個程序中的多個執行緒共享所在程序的記憶體資源,當多個執行緒在同一時刻同時訪問同一種共享資源時,需要相互協調,以避免出現資料的不一致和覆蓋等問題,執行緒之間的協調和通訊的就叫做執行緒的同步問題,執行緒同步的思路 讓多個執行緒依次訪問共享資源,而不是並行 mutex被建立時可以有初始值,表示mute...