这个类的最大且唯一的作用呢,是规定锁的顺序,《c++并发编程实战》这本书中给了一个避免死锁的建议,那就是用规定的顺序来将多个锁进行上锁,这样就可以避免顺序带来的死锁问题;
直接上代码:
#define UL unsigned long
class hierarchical_mutex {
static thread_local UL this_thread_hierarchical;//当前最新调用的层次
UL previous;//上一个锁的层次值
UL const hierarchical_value;
std::mutex mtx;
void check_hierarchical_value() {
if (this_thread_hierarchical <= hierarchical_value) {
throw std::logic_error("mutex hierarchy violated");
}
}
void update_hierarchical_value() {
previous = this_thread_hierarchical;
this_thread_hierarchical = hierarchical_value;
}
public:
hierarchical_mutex(UL value)
:hierarchical_value(value),previous(0){}
void lock() {
check_hierarchical_value();
mtx.lock();
update_hierarchical_value();
}
void unlock() {
mtx.unlock();
update_hierarchical_value();
}
bool try_lock() {
check_hierarchical_value();
if (!mtx.try_lock()) {
return false;
}
update_hierarchical_value();
return true;
}
~hierarchical_mutex() {
this->unlock();
}
};
thread_local UL hierarchical_mutex::this_thread_hierarchical = ULONG_MAX;
实现这个算法的变量有3个,一个是线程中所有hierarchical_mutex实例共享的;this_thread_hierarchical变量[HTH]和每个实例都有的previous[P],hierarchical_value[HV];
这个算法是靠这些变量维护的:
线程中lock一个锁,HTH就会被赋值为该锁的HV,然后下次上锁的时候就只能给比HTH小的HV锁上锁了,否则就会throw error;