pao*_*olo 6 c++ multithreading mutex deadlock
A. Williams在他的《C++ Concurrency in Action》一书中引入了锁层次结构的概念作为死锁避免机制。下面,我报告了一个实现的精简版本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()};
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
说线程A:
mutex.lock();(1)检查false;HierarchicalMutex::Mutex_;HierarchicalMutex::current_level并将其设置为1.此时,线程B:
mutex.lock();(1)到true。这意味着线程B将抛出异常;但我希望它等到线程A解锁mutex。
我的问题是:
mutex(如我所料)?HierarchicalMutex实现才能让线程B等待而不是抛出?替换<=检查是否足够?(1)<此时,线程B:
调用 mutex.lock();
将检查 (1) 评估为 true。
不,不会。current_level被声明为一个thread_local对象。如果您不熟悉这意味着什么,请参阅 C++ 教科书以获取更完整的讨论,但归根结底,current_level每个执行线程中都是一个单独的、离散的对象。在两个执行线程中它都是 0,并且check (1)计算结果为false。