假設乙個例子:有乙個全域性的計數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函式庫 保證了如果乙個執行緒鎖定了乙個互斥量,沒有其他執行緒在同一時間可以成功鎖定這個互斥...