在他的著作“行动中的C++并发性”中,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();
true.
的 check (1)
这意味着线程B将抛出;但我希望它等到线程A解锁mutex。
我的问题是:
mutex (正如我预期的那样)?HierarchicalMutex才能让线程B等待而不是抛出?用<替换<=在check (1)中是否足够
发布于 2022-10-23 15:01:36
在这里,线程B:
调用mutex.lock();
将check (1)计算为true。
不,不会。current_level被声明为thread_local对象。如果您不熟悉这意味着什么,请参阅您的C++教科书,以便进行更完整的讨论,但归根结底,current_level在每个执行线程中都是一个单独的、离散的对象。在两个执行线程中,它都是0,check (1)的计算结果为false。
https://stackoverflow.com/questions/74171933
复制相似问题