執行緒之間的鎖有:互斥鎖、條件鎖、自旋鎖、讀寫鎖、遞迴鎖。一般而言,鎖的功能越強大,效能就會越低。
互斥鎖用於控制多個執行緒對他們之間共享資源互斥訪問的乙個訊號量。也就是說是為了避免多個執行緒在某一時刻同時操作乙個共享資源。例如執行緒池中的有多個空閒執行緒和乙個任務佇列。任何是乙個執行緒都要使用互斥鎖互斥訪問任務佇列,以避免多個執行緒同時訪問任務佇列以發生錯亂。
在某一時刻,只有乙個執行緒可以獲取互斥鎖,在釋放互斥鎖之前其他執行緒都不能獲取該互斥鎖。如果其他執行緒想要獲取這個互斥鎖,那麼這個執行緒只能以阻塞方式進行等待。
使用 :std::mutex
個執行緒想要獲取乙個被使用的自旋鎖,那麼它會一致占用cpu請求這個自旋鎖使得cpu不能去做其他的事情,直到獲取這個鎖為止,這就是「自旋」的含義。
使用 :spinlock_t
寫者:寫者使用寫鎖,如果當前沒有讀者,也沒有其他寫者,寫者立即獲得寫鎖;
否則寫者將等待,直到沒有讀者和寫者。
讀者:讀者使用讀鎖,如果當前沒有寫者,讀者立即獲得讀鎖;否則讀者等待,直到沒有寫者。
操作函式說明
初始化讀寫鎖
pthread_rwlock_init 語法
讀取讀寫鎖中的鎖
pthread_rwlock_rdlock 語法
讀取非阻塞讀寫鎖中的鎖
pthread_rwlock_tryrdlock 語法
寫入讀寫鎖中的鎖
pthread_rwlock_wrlock 語法
寫入非阻塞讀寫鎖中的鎖
pthread_rwlock_trywrlock 語法
解除鎖定讀寫鎖
pthread_rwlock_unlock 語法
銷毀讀寫鎖
pthread_rwlock_destroy 語法
c++17 引入std::shared_mutex
, 底層實現時作業系統提供的讀寫鎖,也就是說,再有多個執行緒對共享資源讀且少許執行緒對共享資源寫的情況下,std::shared_mutex
比std::mutex
效率更高。
std::shared_mutex
提供了lock
方法和unlock
方法分別用於獲取寫鎖和解除寫鎖,提供了lock_shared
方法和unlock_shared
方法分別用於獲取讀鎖和解除讀鎖。一般將寫鎖模式稱為排它鎖( exclusive locking),將讀鎖模式成為共享鎖(shared locking)。
std::unique_lock
對std::shared_mutex
寫鎖管理
std::shared_lock
對std::shared_mutex
讀鎖管理
所謂遞迴鎖,就是在同一執行緒上該鎖是可重入的,對於不同執行緒則相當於普通的互斥鎖。
使用規則:例如函式a需要獲取鎖mutex,函式b也需要獲取鎖mutex,同時函式a中還會呼叫函式b。如果使用std::mutex必然會造成死鎖。但是使用std::recursive_mutex就可以解決這個問題。
使用 :std::recursive_mutex
死鎖至少有兩個互斥量mutex1,mutex2。
以上給出了導致死鎖的四個必要條件,只要系統發生死鎖則以上四個條件至少有乙個成立。事實上迴圈等待的成立蘊含了前三個條件的成立,似乎沒有必要列出然而考慮這些條件對死鎖的預防是有利的,因為可以通過破壞四個條件中的任何乙個來預防死鎖的發生。
常規做法:
std::lock_guard的std::adopt_lock引數
互斥量管理
版本作用
lock_guard
c++11
基於作用域的互斥量管理
unique_lock
c++11
更加靈活的互斥量管理
shared_lock
c++14
共享互斥量管理
scoped_lock
c++17
互斥量避免死鎖的管理
unique_lock 繼承 lock_guard 功能,但是比lock_guard更加靈活,可以降低鎖的粒度。重點介紹unique_lock功能
std::adopt_lock
std::try_to_lock
std::defer_lock
配合 std::defer_lock 使用,可以實時unlock。
使用move或者臨時unique_lock變數返回可以傳遞unique_lock的所有權
unique_lock使用
c++ 中mutex鎖沒有複製建構函式,因此不能直接複製呼叫;需採用指標傳遞,這裡推介使用結合智慧型指標使用
// 定義
std::shared_ptrmtx_ptr;
// 初始化
mtx_ptr = make_shared();
// 使用
std::lock_guardlock(*mtx_ptr);
執行緒二 多執行緒基礎
任務量比較大,通過多執行緒可以提高效率時,需要非同步處理時,占用系統資源,造成阻塞的工作時,都可以採用多執行緒提高效率 執行緒建立 使用者執行緒和守護執行緒 j a分為兩種執行緒 使用者執行緒和守護執行緒 守護執行緒 在程式執行的時候在後台提供一種通用服務的執行緒,比如垃圾 執行緒就是乙個很稱職的守...
C 多執行緒與鎖
多執行緒是小型軟體開發必然的趨勢。c 11將多執行緒相關操作全部整合到標準庫中了,省去了某些坑庫的編譯,真是大大的方便了軟體開發。多執行緒這個庫簡單方便實用,下面給出簡單的例子 include include includeusing namespace std volatile int val m...
C 多執行緒 巢狀鎖
巢狀鎖這個概念,主要是為了根據程式設計中的一種情形引申出來的。什麼情況呢,我們可以具體說明一下。假設你在處理乙個公共函式的時候,因為中間涉及公共資料,所以你加了乙個鎖。但是,有一點比較悲哀。這個公共函式自身也加了乙個鎖,而且和你加的鎖是一樣的。所以,除非你的使用的是訊號量,要不然你的程式一輩子也獲取...