层次锁

为了避免死锁,可以规定加锁的顺序,因此可以使用层次锁来实现。通过给互斥量封装层次值之一属性,可以确保层次值高的线程可以获得层次值低的锁,反之则不行。简单代码实现如下,可以使用stack来保存已经获得锁的层次值。

class HierarchicalMutex {
private:
	mutex inter_mutex_;
	unsigned long const level_value_;
	unsigned long previous_value_;

	static thread_local unsigned long this_thread_value_;

public:
	HierarchicalMutex(unsigned long level_value) :level_value_(level_value),previous_value_(0) {}

	void checkLock() {
		//this_thread_value_是线程本地变量,所以每个线程各存一份,用来保存线程自带的层次值
		//线程获得锁之后,该层次值就成了该线程自带的值了,当该线程试图去获取层次值更高的锁时,这样是不允许的
		if (this_thread_value_ <= level_value_)
		{
			throw logic_error("can not lock\n");
		}
	}

	void lock() {
		checkLock();
		inter_mutex_.lock();
		//获得锁之后,首先将线程原有的值保存下来,然后如果其再去获得一个层次值较小的锁的话,更新值为更小的那个值
		previous_value_ = this_thread_value_;
		this_thread_value_ = level_value_;
	}
	
	void unlock() {
		//如果获得的层次较小的锁释放了,那么该线程的层次值恢复成原有的值
		this_thread_value_ = previous_value_;
		inter_mutex_.unlock();
	}

	bool trylock() {
		checkLock();
		if (!inter_mutex_.try_lock())
		{
			return false;
		}
		previous_value_ = this_thread_value_;
		this_thread_value_ = level_value_;
		return true;
		
	}
};

thread_local unsigned long HierarchicalMutex::this_thread_value_ = ULONG_MAX;

HierarchicalMutex high_lock(10000);
HierarchicalMutex low_lock(500);

void low_func();

void high_func() {
	lock_guard<HierarchicalMutex> lg(high_lock);
	cout << "thread : " << this_thread::get_id() << "get the high lock" << endl;
	low_func();
}

void low_func() {
	lock_guard<HierarchicalMutex> lg(low_lock);
	cout<< "thread : " << this_thread::get_id() << "get the low lock" << endl;
}

int main() {
	
	thread t(high_func);
	t.join();

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值