C 執行緒中幾類鎖的詳解

2022-09-25 03:15:09 字數 2416 閱讀 2937

目錄

多執行緒中的鎖主要有五類:互斥鎖、條件鎖、自旋鎖、讀寫鎖、遞迴鎖。一般而言,所得功能與效能成反比。而且我們一般不使用遞迴鎖(c++提供std::recursive_mutex),這裡不做介紹。

==互斥鎖用於控制多個執行緒對它們之間共享資源互斥訪問的乙個訊號量。==也就是說為了避免多個執行緒在某一時刻同時操作乙個共享資源,例如乙個全域性變數,任何乙個執行緒都要使用初始鎖互斥地訪問,以避免多個執行緒同時訪問發生錯亂。

在某一時刻只有乙個執行緒可以獲得互斥鎖,在釋放互斥鎖之前其它執行緒都不能獲得互斥鎖,以阻塞的狀態在乙個等待佇列中等待。

標頭檔案:#include

型別:std::std::mutex、std::lock_guard

用法:在c++中,通過構造std::mutex的例項建立互斥單元,呼叫成員函式lock()來鎖定共享資源,呼叫unlock()來解鎖。不過一般不使用這種解決方案,更多的是使用c++標準庫中的std::lock_guard類模板,實現了乙個互斥量包裝程式,提供了一種方便的raii風格的機制在作用域塊中。

關於raii慣用法的介紹:。。。

示例**:

#include

#include //c++11執行緒庫是跨平台的

#include //c++互斥鎖

#include

#include

int g_num = 0;

std::mutex g_mutex;

void threadfunc(int a)

}int main()

sleep(2000);

cout << "g_num:" << g_num << endl;

return 0;

}//高階版,將上述main()函式的函式名更改,再更改以下的maintest()即可執行。兩個方法的執行的結果相同,原理也相同。

int maintest()

for (auto begin = ts.begin(); begin != ts.end(); begin

(*begin)->join();

sleep(2000);

cout << "g_num:" << g_num << endl;

return 0;

}tips:注意std::cout和std::end都是執行緒不安全的,所以才會出現執行緒1和執行緒3在一行,原因就是執行緒1未執行cout<

具體c++11中thread庫join和detach的區別可參考:

條件鎖就是所謂的條件變數,當某乙個執行緒因為某個條件未滿足時可以使用條件變數使該程式處於阻塞狀態,一旦條件滿足則以「訊號量」的方式喚醒乙個因為該條件而被阻塞的執行緒。最為常見的就是再執行緒池中,初始情況下因為沒有任務使得任務隊列為空,此時執行緒池中的執行緒因為「任務隊列為空」這個條件處於阻塞狀態。一旦有www.cppcns.com任務進來,就會以訊號量的方式喚醒該執行緒來處理這個任務。

互斥鎖和條件鎖都是比較常見的鎖,比較容易理解。接下來用互斥鎖和自旋鎖的原理相互比較,來理解自旋鎖。

假設我們有一台計算機,該計算機擁有兩個處理器core1和core2.現在在這台計算機上執行兩個執行緒:t1和t2,且t1和t2分別在處理器core1和core2上面執行,兩個執行緒之間共享乙份公共資源public。

首先我們說明互斥鎖的工作原理,互斥鎖是一種sleep-waiting的鎖。假設執行緒t1訪問公共資源public並獲得互斥鎖,同時在core1處理器上執行,此時執行緒t2也想要訪問這份公共資源public(即想要獲得互斥鎖),但是由於t1正在使用public使得t2被阻塞。當t2處於阻塞狀態時,t2被放入等待佇列中,處理器core2會去處理其它的任務而不必一直等待(忙等)。也就是說處理器不會因為執行緒被阻塞而空閒,它會去處理其它事務。

然後我們說明自旋鎖的工作原理,自旋鎖是一種busy-waiting的鎖。也就是說,如果t1正在使用public,而t2也想使用public,此時t2肯程式設計客棧定是得不到這個自旋鎖的。與互斥鎖相反,此時執行t2的處理器core2會一直不斷地迴圈檢查public使用可用(自旋鎖請求),直到獲得到這個自旋鎖為止。

從「自旋鎖」的名稱也可以看出,如果乙個執行緒想要獲得乙個被使用的自旋鎖,那麼它會一直占用cpu請求這個自旋鎖使得cpu不能去做其它的事情,知道獲取這個鎖為止,這就是「自旋」的含義。當發生阻塞時,互斥鎖可以讓cpu去處理其它的事務,但自旋鎖讓cpu一直不斷迴圈請求獲取這個鎖。通過比較,我們可以明顯的得出結論:「自旋鎖」是比較消耗cpu的。

讀寫鎖我們可以借助於「讀者-寫者」問題進行理解。接下來我們簡單說下「讀者-寫者」問題。

計算機中某些資料被多個程序共享,對資料庫的操作有兩種:一種是讀操作,就是從資料庫中讀取資料不會修改資料庫中內容;另一種就是寫操作,寫操作會修改資料庫中存放的資料。因此可以得到我們允許在資料庫上同時執行多個「讀」操作,但是pqrqo某一時刻只能在資料庫上有乙個「寫」操作來更新資料。這就是簡單的讀者-寫者模型。

本文標題: c++執行緒中幾類鎖的詳解

本文位址: /ruanjian/c/439220.html

c 執行緒中的幾種鎖

這個是在中興面試中被面試問到的乙個題 你知道執行緒中的自旋鎖麼?我當時一臉懵逼,不知道。回來後整理下,在這裡對執行緒中的鎖進行乙個學習。執行緒之間的鎖有 互斥鎖 條件鎖 自旋鎖 讀寫鎖 遞迴鎖。一般而言,鎖的功能越強大,效能就會越低。1 互斥鎖 互斥鎖用於控制多個執行緒對他們之間共享資源互斥訪問的乙...

c 執行緒中的幾種鎖

執行緒之間的鎖有 互斥鎖 條件鎖 自旋鎖 讀寫鎖 遞迴鎖。一般而言,鎖的功能越強大,效能就會越低。1 互斥鎖 互斥鎖用於控制多個執行緒對他們之間共享資源互斥訪問的乙個訊號量。也就是說是為了避免多個執行緒在某一時刻同時操作乙個共享資源。例如執行緒池中的有多個空閒執行緒和乙個任務佇列。任何是乙個執行緒都...

c 執行緒中的幾種鎖

這個是在中興面試中被面試問到的乙個題 你知道執行緒中的自旋鎖麼?我當時一臉懵逼,不知道。回來後整理下,在這裡對執行緒中的鎖進行乙個學習。執行緒之間的鎖有 互斥鎖 條件鎖 自旋鎖 讀寫鎖 遞迴鎖。一般而言,鎖的功能越強大,效能就會越低。1 互斥鎖 互斥鎖用於控制多個執行緒對他們之間共享資源互斥訪問的乙...