在他的C Concurrency in Action一書中,A. Williams 介紹了鎖層次結構的概念作為一種死鎖避免機制。下面,我報告了一個精簡版的HierarchicalMutex實作(摘自書中):
class HierarchicalMutex {
private:
std::mutex Mutex_;
unsigned const Level_;
unsigned PrevLevel_{0};
static thread_local unsigned current_level;
public:
explicit HierarchicalMutex(unsigned level) : Level_{level} {}
void lock() {
if (current_level <= this->Level_) { // (1)
// I can only lock a mutex with a lower level than the currently
// locked one.
throw std::logic_error("lock: Out of order");
}
this->Mutex_.lock();
this->PrevLevel_ = std::exchange(current_level, this->Level_);
}
// try_lock implemented accordingly [...]
void unlock() {
if (current_level != this->Level_)
throw std::logic_error("unlock: Out of order");
current_level = this->PrevLevel_;
this->Mutex_.unlock();
}
};
// current_level initialized to UINT_MAX so that, in the beginning, any
// HierarchicalMutex may be locked.
thread_local unsigned HierarchicalMutex::current_level{
std::numeric_limits<unsigned>::max()};
Les 假設執行緒A和B競爭鎖定 的實體HierarchicalMutex,如下面的代碼所示:
int main() {
HierarchicalMutex mutex{1};
std::thread threadA{[&mutex] { std::scoped_lock sl{mutex}; }};
std::thread threadB{[&mutex] { std::scoped_lock sl{mutex}; }};
threadB.join();
threadA.join();
}
說執行緒A:
- 來電
mutex.lock(); - 成功評估檢查
(1)到false; - 鎖
HierarchicalMutex::Mutex_; - 更新
HierarchicalMutex::current_level并將其設定為1.
此時,執行緒B:
- 來電
mutex.lock(); - 將檢查評估
(1)為true。
這意味著執行緒B將拋出;但我希望它等到執行緒A解鎖mutex。
我的問題是:
- 我描繪的執行流程甚至可能嗎?
- 如果是這樣,執行緒B拋出是否正確,還是應該等待執行緒A解鎖
mutex(如我所料)? - 如果我的期望是正確的,應該如何
HierarchicalMutex實作執行緒B等待而不是拋出?是否足以替換<=檢查?(1)<
uj5u.com熱心網友回復:
此時,執行緒B:
呼叫 mutex.lock();
將檢查 (1) 評估為真。
不,不會的。current_level被宣告為thread_local物件。如果您不熟悉這意味著什么,請參閱您的 C 教科書以獲得更完整的討論,但歸結current_level為每個執行執行緒中的一個單獨的離散物件。在兩個執行執行緒中,它都是 0,check (1)計算結果為false.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/520369.html
標籤:C 多线程互斥体僵局
上一篇:當我嘗試第二次加載時,為什么我的queue.get()卡在無限回圈中?
下一篇:java并發與并行
