python在內建的threading
模組中提供了lock
類,該類相當於互斥鎖
,可以保護各執行緒資料結構不被破壞。
案例:新建乙個counter
類,統計感測器取樣獲得的樣本數量。
### 計數器
class
counter
(object):
def__init__
(self)
: self.count =
0def
increment
(self,offset)
: self.count += offset
### 感測器
defwoker
(sensor_index,how_many,counter)
:for _ in
range
(how_many)
:## read from the sensor
##....
counter.increment(1)
#### run_threads函式
defrun_threads
(func,how_many,counter)
: threads =
for i in
range(5
):args =
(i,how_many,counter)
thread = thread(target=func,args = args)
thread.start(
)for thread in threads:
thread.joint(
)if __name__==
'__main__'
:###執行
how_many =
10**
5 counter = counter(
) run_threads(worker,how_many,counter)
print(5
*how_many,counter.count)
輸出結果:
500000
278328
可以看出,兩者資料相差較大,這是由於程式在執行self.count += offset
語句時,並非原子操作,而是可以分解為:
value =
getattr
(counter,
'count'
)result = value + offset
setattr
(counter,
'count'
,result)
上述三個操作,在任意兩個操作之間都可能發生執行緒切換,這種頻繁的執行緒切換,交錯執行可能會令執行緒把舊的value
設定給counter
。
因此,在不加鎖的前提下,允許多條執行緒修改同一物件,那麼程式的資料結構可能會遭到破壞。我們可以用
互斥鎖
保護counter
物件,使得多個執行緒同時訪問value
值的時候,不會將該值破壞。同一時刻,只有乙個執行緒能夠獲得這把鎖。如下:
class
lockingcounter
(object):
def__init__
(self)
: self.lock = lock(
) self.count =
0def
increment
(self,offset)
:with self.lock:
###判斷鎖狀態
self.count += offset
if __name__ ==
'__main__'
: counter = lockingcounter(
) run_threads(worker,how_many,counter)
print(5
*how_many,counter.count)
基本執行緒同步 在Lock中使用多個條件
在lock中使用多個條件 乙個鎖可能伴隨著多個條件。這些條件宣告在condition介面中。這些條件的目的是允許執行緒擁有鎖的控制並且檢查條件是否為true,如果是false,那麼執行緒將被阻塞,直到其他執行緒喚醒它們。condition介面提供一種機制,阻塞乙個執行緒和喚醒乙個被阻塞的執行緒。在併...
使用Lock解決執行緒安全問題
lock介面的概述 lock是jdk1.5 新特性 專門用來實現執行緒安全的技術 lock介面的常用實現類 reentrantlock 互斥鎖 lock介面的常用方法 void lock 獲取鎖 void unlock 釋放鎖 注意事項 獲取鎖和釋放鎖的 必須成對出現。public class ti...
C 多執行緒Lock鎖定的使用例子 多執行緒執行緒同步)
這個例子是乙個模擬多個人在多台提款機上同時提取乙個賬戶的款的情況。在訪問的過程中 可能 a執行緒取了100 而b執行緒那邊還看見賬戶上沒少掉那100快,所以導致資料不統一,賦值出現問題。下面 則可以測試出加上lock鎖定 與 不加的區別。先上兩個圖。第乙個 加了lock的程式 加了的 資料每一條都是...