之前遇到乙個問題,訊號量和互斥鎖的區別是什麼。一時忘了思考,今天才想到這個問題,翻閱知乎和stackoverflow,理解了之後做簡單整理
mutex,互斥鎖,用於序列化對一部分可重入**的訪問,這些**不能由多個執行緒同時執行
semaphore,訊號量,將共享資源的併發使用者數限制為最大數量
mutex:假設我們有關鍵部分執行緒t1想要訪問它然後它遵循以下步驟:
鎖使用關鍵部分
開鎖二進位制訊號量:它基於信令等待和訊號工作。等待(s)將「s」值減少乙個通常「s」值用值「1」初始化,訊號(s)將「s」值增加1。如果「s」值為1表示沒有人使用臨界區,則值為0表示臨界區正在使用中。假設執行緒t2正在使用臨界區,那麼它遵循以下步驟:
wait(s)//最初s值在呼叫之後等於它的值減1,即0
使用關鍵部分
signal(s)//現在s值增加,變為1
一般人不明白semaphore和mutex的區別,根本原因是不知道semaphore的用途。semaphore的用途,一句話:排程執行緒。 有的人用semaphore也可以把上面例子中的票「保護"起來以防止共享資源衝突,必須承認這是可行的,但是semaphore不是讓你用來做這個的;如果你要做這件事,請用mutex。
在網上、包括stackoverflow等著名論壇上,有乙個流傳很廣的廁所例子: mutex是乙個廁所一把鑰匙,誰搶上鑰匙誰用廁所,誰沒搶上誰就等著;semaphore是多個同樣廁所多把同樣的鑰匙 ---- 只要你能拿到一把鑰匙,你就可以隨便找乙個空著的廁所進去。 事實上,這個例子對初學者、特別是剛剛學過mutex的初學者來說非常糟糕 ----- 我第一次讀到這個例子的第一反應是:semaphore是執行緒池???所以,請務必忘記這個例子。 另外,有人也會說:mutex就是semaphore的value等於1的情況。 這句話不能說不對,但是對於初學者來說,請先把這句話視為錯誤;等你將來徹底融會貫通這部分知識了,你才能真正理解上面這句話到底是什麼意思。總之請務必記住:mutex幹的活兒和semaphore幹的活兒不要混起來。
在這裡,我模擬乙個最典型的使用semaphore的場景: a源自乙個執行緒,b源自另乙個執行緒,計算c = a + b也是乙個執行緒。(即一共三個執行緒)
顯然,第三個執行緒必須等第
一、二個執行緒執行完畢它才能執行。 在這個時候,我們就需要排程執行緒了:讓第
一、二個執行緒執行完畢後,再執行第三個執行緒。 此時,就需要用semaphore了。
inta, b, c;
void
geta()
void
getb()
void
getc()
t1 =thread_create(geta);
t2 =thread_create(getb);
t3 =thread_create(getc);
thread_join(t3);
////
semaphore_increase對應sem_post
//semaphore_decrease對應sem_wait
這就是semaphore最典型的用法。 說白了,排程執行緒,就是:一些執行緒生產(increase)同時另一些執行緒消費(decrease),semaphore可以讓生產和消費保持合乎邏輯的執行順序。而執行緒池是程式設計師根據具體的硬體水平和不同的設計需求、為了達到最佳的執行效果而避免反覆新建和釋放執行緒同時對同一時刻啟動的執行緒數量的限制,這完全是兩碼事。 比如如果你要計算z = a + b +...+ x + y ...的結果,同時每個加數都是乙個執行緒,那麼計算z的執行緒和每個加數的執行緒之間的邏輯順序是通過semaphore來排程的;而至於你執行該程式的時候到底要允許最多同時啟動幾個執行緒,則是用執行緒池來實現的。
簡而言之,鎖是服務於共享資源的;而semaphore是服務於多個執行緒間的執行的邏輯順序的。
請回頭看那個讓大家忘記的廁所例子。我之所以讓大家忘記這個例子,是因為如果你從這個角度去學習semaphore的話,一定會和mutex混為一談。semaphore的本質就是排程執行緒---- 在充分理解了這個概念後,我們再看這個例子。
semaphore是通過乙個值來實現執行緒的排程的,因此借助這種機制,我們也可以實現對執行緒數量的限制。而當我們把執行緒數量限制為1時,你會發現:共享資源受到了保護 ------ 任意時刻只有乙個執行緒在執行,因此共享資源當然等效於受到了保護。但是我要再提醒一下,如果你要對共享資源進行保護,請用mutex;到底應該用條件鎖還是用semaphore,請務必想清楚。通過semaphore來實現對共享資源的保護的確可行但是是對semaphore的一種錯用。
只要你能搞清楚鎖、條件鎖和semaphore為什麼而生、或者說它們是面對什麼樣的設計需求、為了解決什麼樣型別的問題才出現的,你自然就不會把他們混淆起來。
訊號量與互斥鎖的區別
訊號量用在多執行緒多工同步的,乙個執行緒完成了某乙個動作就通過訊號量告訴別的執行緒,別的執行緒再進行某些動作 大家都在semtake的時候,就阻塞在 互斥鎖是用在多執行緒多工互斥的,乙個執行緒占用了某乙個資源,那麼別的執行緒就無法訪問,直到這個執行緒unlock,其他的執行緒才開始可以利用這個資源。...
訊號量與互斥鎖的區別
儘管兩個概念有點類似,但是他們的側重點不一樣,不難看出,mutex是semaphore的一種特殊情況 n 1時 也就是說,完全可以用後者替代前者。但是,因為mutex較為簡單,且效率高,所以在必須保證資源獨佔的情況下,還是採用這種設計。semaphore可以被抽象為五個操作 1.建立 create,...
訊號量與互斥鎖
訊號量與普通整型變數的區別 訊號量 semaphore 是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作 wait semap signal semap 來進行訪問 操作也被成為pv原語 p 於dutch proberen 測試 v 於 dutch verhogen 增加 而普通整型變數則...