c 多執行緒鎖(c 11)

2021-10-05 13:39:01 字數 2384 閱讀 9199

mutex屬於sleep-waiting型別的鎖。例如在乙個雙核的機器上有兩個執行緒(執行緒a和執行緒b),它們分別執行在core0和core1上。假設執行緒a想要通過pthread_mutex_lock操作去得到乙個臨界區的鎖,而此時這個鎖正被執行緒b所持有,那麼執行緒a就會被阻塞,core0會在此時進行上下文切換(context switch)將執行緒a置於等待佇列中,此時core0就可以執行其它的任務而不必進行忙等待。

mutex 類

std::mutex,最基本的 mutex 類。

std::recursive_mutex,遞迴 mutex 類。

std::time_mutex,定時 mutex 類。

std::recursive_timed_mutex,定時遞迴 mutex 類。

std::mutex是c++11 中最基本的互斥量,std::mutex 物件提供了獨佔所有權的特性——即不支援遞迴地對 std::mutex 物件上鎖,而 std::recursive_lock 則可以遞迴地對互斥量物件上鎖。

std::mutex 的成員函式

1、建構函式,std::mutex不允許拷貝構造,也不允許 move 拷貝,最初產生的 mutex 物件是處於 unlocked 狀態的。

2、lock(),呼叫執行緒將鎖住該互斥量。執行緒呼叫該函式會發生下面 3 種情況:(1). 如果該互斥量當前沒有被鎖住,則呼叫執行緒將該互斥量鎖住,直到呼叫 unlock之前,該執行緒一直擁有該鎖。(2). 如果當前互斥量被其他執行緒鎖住,則當前的呼叫執行緒被阻塞住。(3). 如果當前互斥量被當前呼叫執行緒鎖住,則會產生死鎖(deadlock)。

3、unlock(), 解鎖,釋放對互斥量的所有權。

4、try_lock(),嘗試鎖住互斥量,如果互斥量被其他執行緒占有,則當前執行緒也不會被阻塞。執行緒呼叫該函式也會出現下面 3 種情況,(1). 如果當前互斥量沒有被其他執行緒占有,則該執行緒鎖住互斥量,直到該執行緒呼叫 unlock 釋放互斥量。(2). 如果當前互斥量被其他執行緒鎖住,則當前呼叫執行緒返回 false,而並不會被阻塞掉。(3). 如果當前互斥量被當前呼叫執行緒鎖住,則會產生死鎖(deadlock)。

std::recursive_mutex

與 std::mutex 一樣,也是一種可以被上鎖的物件,但是和 std::mutex 不同的是,std::recursive_mutex 允許同乙個執行緒對互斥量多次上鎖(即遞迴上鎖),來獲得對互斥量物件的多層所有權,std::recursive_mutex 釋放互斥量時需要呼叫與該鎖層次深度相同次數的 unlock(),可理解為 lock() 次數和 unlock() 次數相同,除此之外,std::recursive_mutex 的特性和 std::mutex 大致相同。

std::time_mutex比 std::mutex 多了兩個成員函式,try_lock_for(),try_lock_until()。

try_lock_for 函式接受乙個時間範圍,表示在這一段時間範圍之內執行緒如果沒有獲得鎖則被阻塞住(與 std::mutex 的 try_lock() 不同,try_lock 如果被呼叫時沒有獲得鎖則直接返回 false),如果在此期間其他執行緒釋放了鎖,則該執行緒可以獲得對互斥量的鎖,如果超時(即在指定時間內還是沒有獲得鎖),則返回 false。

try_lock_until 函式則接受乙個時間點作為引數,在指定時間點未到來之前執行緒如果沒有獲得鎖則被阻塞住,如果在此期間其他執行緒釋放了鎖,則該執行緒可以獲得對互斥量的鎖,如果超時(即在指定時間內還是沒有獲得鎖),則返回 false。

std::unique_lock與std::lock_guard

unique_lock比lock_guard使用更加靈活,功能更加強大。

使用unique_lock需要付出更多的時間、效能成本。

自旋鎖(spin lock)

自旋鎖與互斥鎖有點類似,只是自旋鎖不會引起呼叫者睡眠,如果自旋鎖已經被別的執行單元保持,呼叫者就一直迴圈在那裡看是否該自旋鎖的保持者已經釋放了鎖,「自旋鎖」的作用

是為了解決某項資源的互斥使用。因為自旋鎖不會引起呼叫者睡眠,所以自旋鎖的效率遠高於互斥鎖。

自旋鎖的不足之處:

自旋鎖一直占用著cpu,他在未獲得鎖的情況下,一直執行(自旋),所以占用著cpu,如果不能在很短的時間內獲得鎖,這無疑會使cpu效率降低。

在用自旋鎖時有可能造成死鎖,當遞迴呼叫時有可能造成死鎖,呼叫有些其他函式也可能造成死鎖,如 copy_to_user()、copy_from_user()、kmalloc()等。

因此我們要慎重使用自旋鎖,自旋鎖只有在核心可搶占式或smp的情況下才真正需要,在單cpu且不可搶占式的核心下,自旋鎖的操作為空操作。自旋鎖適用於鎖使用者保持鎖時間比較短的情況下,若持鎖時間太長,效能降低

讀寫鎖

C 11 多執行緒與鎖

多執行緒是小型軟體開發必然的趨勢。c 11將多執行緒相關操作全部整合到標準庫中了,省去了某些坑庫的編譯,真是大大的方便了軟體開發。多執行緒這個庫簡單方便實用,下面給出簡單的例子 include include include using namespace std volatile int val ...

C 11 多執行緒

新特性之描述 雖然 c 11 會在語言的定義上提供乙個記憶體模型以支援執行緒,但執行緒的使用主要將以 c 11 標準庫的方式呈現。c 11 標準庫會提供型別 thread std thread 若要執行乙個執行緒,可以建立乙個型別 thread 的實體,其初始引數為乙個函式物件,以及該函式物件所需要...

c 11 多執行緒

1.多執行緒的原理 同一時間內,cpu只能處理1條執行緒,只有1條執行緒在工作 執行 多執行緒併發 同時 執行,其實是cpu快速地在多條執行緒之間排程 切換 如果cpu排程執行緒的時間足夠快,就造成了多執行緒併發執行的假象。思考 如果執行緒非常非常多,會發生什麼情況?cpu會在n多執行緒之間排程,c...