python多執行緒程式設計 使用互斥鎖同步執行緒

2021-08-16 14:04:04 字數 2399 閱讀 3731

假設乙個例子:有乙個全域性的計數num,每個執行緒獲取這個全域性的計數,根據num進行一些處理,然後將num加1。很容易寫出這樣的**:

# encoding: utf-8

import threading

import time

class

mythread

(threading.thread):

defrun

(self):

global num

time.sleep(1)

num = num+1

msg = self.name+' set num to '+str(num)

print msg

num = 0

deftest

():for i in range(5):

t = mythread()

t.start()

if __name__ == '__main__':

test()

得到結果:

thread-1

setnumto1

thread-2

setnumto2

thread-3

setnumto3

thread-4

setnumto5

thread-5

setnumto5

process finished with exit code 0

但是執行結果是不正確的:

問題產生的原因就是沒有控制多個執行緒對同一資源的訪問,對資料造成破壞,使得執行緒執行的結果不可預期。這種現象稱為「執行緒不安全」。

上面的例子引出了多執行緒程式設計的最常見問題:資料共享。當多個執行緒都修改某乙個共享資料的時候,需要進行同步控制。

執行緒同步能夠保證多個執行緒安全訪問競爭資源,最簡單的同步機制是引入互斥鎖。互斥鎖為資源引入乙個狀態:鎖定/非鎖定。某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為「鎖定」,其他執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成「非鎖定」,其他的執行緒才能再次鎖定該資源。互斥鎖保證了每次只有乙個執行緒進行寫入操作,從而保證了多執行緒情況下資料的正確性。

threading模組中定義了lock類,可以方便的處理鎖定:

#建立鎖

mutex = threading.lock()

#鎖定mutex.acquire([timeout])

#釋放mutex.release()

其中,鎖定方法acquire可以有乙個超時時間的可選引數timeout。如果設定了timeout,則在超時後通過返回值可以判斷是否得到了鎖,從而可以進行一些其他的處理。

使用互斥鎖實現上面的例子的**如下:

import threading

import time

class

mythread

(threading.thread):

defrun

(self):

global num

time.sleep(1)

if mutex.acquire(1):

num = num+1

msg = self.name+' set num to '+str(num)

print msg

mutex.release()

num = 0

mutex = threading.lock()

deftest

():for i in range(5):

t = mythread()

t.start()

if __name__ == '__main__':

test()

執行結果如下:

thread-1

setnumto1

thread-2

setnumto2

thread-3

setnumto3

thread-4

setnumto4

thread-5

setnumto5

process finished with exit code 0

可以看到,加入互斥鎖後,執行結果與預期相符

同步阻塞

當乙個執行緒呼叫鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。每次只有乙個執行緒可以獲得鎖。如果此時另乙個執行緒試圖獲得這個鎖,該執行緒就會變為「blocked」狀態,稱為「同步阻塞」(參見多執行緒的基本概念)。

直到擁有鎖的執行緒呼叫鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。執行緒排程程式從處於同步阻塞狀態的執行緒中選擇乙個來獲得鎖,並使得該執行緒進入執行(running)狀態。

互斥鎖最基本的內容就是這些,下一節將討論可重入鎖(rlock)和死鎖問題。

python多執行緒程式設計 使用互斥鎖同步執行緒

usr bin env python coding utf 8 import time,threading 假定這是你的銀行存款 balance 0 muxlock threading.lock defchange it n 先存後取,結果應該為0 global balance balance ba...

python 使用多執行緒進行併發程式設計 互斥鎖的使用

import threading import time python的thread模組是比較底層的模組,python的threading模組是對thread做了一些包裝的,可以更加方便的被使用 多執行緒程式的執行順序是不確定的,當執行緒被阻塞 blocked 時,執行緒掛起,阻塞結束後,執行緒進入...

多執行緒程式設計 互斥鎖

多執行緒程式設計 互斥鎖 1 引言 互斥鎖,是一種訊號量,常用來防止兩個程序或執行緒在同一時刻訪問相同的共享資源。可以保證以下三點 1 原子性 把乙個互斥量鎖定為乙個原子操作,這意味著作業系統 或pthread函式庫 保證了如果乙個執行緒鎖定了乙個互斥量,沒有其他執行緒在同一時間可以成功鎖定這個互斥...