試想這乙個情況,兩個同時執行的執行緒,它們都需要改寫共享記憶體中的某乙個資料,那會發生什麼情況呢?
我們當然希望它們來安裝順序來,乙個執行緒先讀取,然後改寫,再到另乙個執行緒讀取改寫。
但很多情況下,並不是這樣了,因為這兩個執行緒它們之間是並不知道對方也同時在訪問這個共享記憶體。
於是,可能出現下面這種我們並不想讓它發生的情況:
兩個執行緒(不妨記作a,b)同時讀取了共享記憶體,獲得了相同的資料。
其中a執行緒運算完後,改寫了共享記憶體,然而此時b執行緒並不知道共享記憶體已經被改寫,仍然用著改寫之前的資料進行運算。
b執行緒得到了用改寫之前資料得出的運算結果,並改寫共享記憶體。
不難發現,雖然a,b執行緒都執行完了,但對於這個資料卻只有b執行緒的操作,而a執行緒的操作被覆蓋了。
互斥鎖就為解決這一類問題提供了乙個方案。
mux.
lock()
mux.
unlock
()
通過lock來加鎖,如果此時mux是被鎖上的,那麼lock函式就會阻塞,直到mux被unlock為止。
如果乙個鎖一直被鎖上,造成了某些執行緒阻塞,就稱之為死鎖。
造成死鎖的常見情況:
mux :=
&sync.mutex
mutex在同乙個時間內只有乙個執行緒能獲得鎖,
但假設現在有多個執行緒需要讀取共享記憶體的某個資料,且這些執行緒並不會修改共享記憶體,那這樣用mutex 乙個乙個按順序來讀取不免有些效率低下。
mux :=
&sync.rwmutex
mux.
lock()
mux.
unlock()
mux.
rlock()
mux.
runlock
()
rwmutex就很好地解決了並行讀取的情況。
最後通過經典的生產者消費者模型來更好地理解互斥鎖。
C 並行程式設計 之 互斥鎖的使用
在並行程式設計中,訪問臨界區是經常會遇到的問題,加鎖,釋放鎖是經常會使用到的解決方式。例如 lock oneobject lock會呼叫system.threading.monitor.enter方法,然後通過 system.threading.monitor.exit來進行釋放。上面的 等同與 b...
多程序中的程序鎖(互斥鎖)
以下例項中 import threading lock threading.lock num 0def work1 asd global num for i in range asd num 1print 在當前的執行緒修改過後的num是 num defwork2 asd global num fo...
Mysql 中互斥鎖的使用
本文介紹如在在多執行緒mysql 開發中使用互斥鎖。mysql自己對c 的mutex又進行了一次封裝,封裝的 可以在include mysql psi mysql thread.h 中找到。下面大概地介紹下如何使用互斥鎖。鎖的生命週期大體為 初始化鎖 上鎖 解鎖 銷毀鎖。注 表示0個或多個。初始化鎖...