105  
查询码:00000090
使用层次锁来避免线程死锁
作者: 董康康 于 2020年06月30日 发布在分类 / 物联网组 / 第三方代理网关 下,并于 2020年06月30日 编辑

#include "iostream"
#include "stdexcept"
#include "thread"
#include "mutex"
#include "climits"
#include "thread_guard.h"
using namespace std;
 
class hierarchical_mutex {
private:
std::mutex internal_mutex;
std::mutex data_mutex;
unsigned long const hierarchy_value;
// 保存上一次的层次值,该锁不能重入,所以只需要一个简单数据类型来保存
unsigned long previous_hierarchy_value;
// 当前层次值
static thread_local unsigned long this_thread_hierarchy_value;
void check_for_hierarchy_violation() 
{
// 当前线程锁定了更低等级的或者是同等级的锁
if (this_thread_hierarchy_value <= hierarchy_value)
{
throw std::logic_error("mutex hierarchy violated");
}
}
void update_hierarchy_value() 
{
// 保存当前层次值
previous_hierarchy_value = this_thread_hierarchy_value; 
// 改变当前层次值
this_thread_hierarchy_value = hierarchy_value; 
}
public:
explicit hierarchical_mutex(unsigned long value) 
:hierarchy_value(value),previous_hierarchy_value(0){}
void lock()
{
check_for_hierarchy_violation();
internal_mutex.lock();
lock_guard<std::mutex> lock(data_mutex);
update_hierarchy_value();
}
void unlock()
{
internal_mutex.unlock();
lock_guard<std::mutex> lock(data_mutex);
this_thread_hierarchy_value = previous_hierarchy_value;

}
bool try_lock() 
{
check_for_hierarchy_violation();
if (!internal_mutex.try_lock())
return false;
lock_guard<std::mutex> lock(data_mutex);
update_hierarchy_value();
return true; 
}
};
thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value = ULONG_MAX;
 
struct Data {
hierarchical_mutex m;
int data; 
Data(unsigned long hierarchical, int data) 
:m(hierarchical), data(data) {}
void swap(Data & d) 
{
lock_guard<hierarchical_mutex> lock1(m);
std::chrono::seconds dura(1);
std::this_thread::sleep_for(dura);
lock_guard<hierarchical_mutex> lock2(d.m);
std::swap(d.data, data);
}
};
 



 推荐知识

 历史版本

修改日期 修改人 备注
2020-06-30 19:56:39[当前版本] 董康康 创建版本

知识分享平台 -V 4.8.7 -wcp