C++并发与多线程-使用层次锁防止死锁

       为防止死锁,其中一种简单的办法是顺序的加锁。而使用层次锁可以减轻程序员的负担,检查运行时是否遵循了约定。其思路是将应用程序分层,当代码试图锁定一个互斥元的时候检查当前线程是不是已经有一个比较低级的互斥元在锁的状态了。因此锁的顺序只能先锁层级高的锁再锁层级低的锁。

//hierarchical_mutex.h文件

#pragma once
#include 
class hierarchical_mutex {
public:
	static thread_local unsigned long this_thread_hierarchy_value;

	explicit hierarchical_mutex(unsigned long value) :_hierarchy_value(value), _previous_hierarchy_value(0){};
	void lock();
	void unlock();
	bool try_lock();

private:
	unsigned long const _hierarchy_value;
	unsigned long _previous_hierarchy_value;
	void check_hierarchy();
	void update_hierarchy();
	std::mutex _internal_lock;
};
//hierarchical_mutex.cpp文件

#include "pch.h"
#include "hierarchical_mutex.h"
#include 

thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value = ULONG_MAX;

void hierarchical_mutex::lock()
{
	check_hierarchy();
	_internal_lock.lock();
	update_hierarchy();
}

void hierarchical_mutex::unlock()
{
	this_thread_hierarchy_value = _previous_hierarchy_value;
	_internal_lock.unlock();
}

bool hierarchical_mutex::try_lock()
{
	check_hierarchy();
	if (_internal_lock.try_lock()) {
		update_hierarchy();
		return true;
	}
	return false;
}

void hierarchical_mutex::check_hierarchy()
{
	if (_hierarchy_value >= this_thread_hierarchy_value) {
		//throw std::logic_error("错误!! 层次锁套用顺序不对。");
		std::cout << "error !!! 层次锁套用顺序不对。" << std::endl;
	}
}

void hierarchical_mutex::update_hierarchy()
{
	_previous_hierarchy_value = this_thread_hierarchy_value;
	this_thread_hierarchy_value = _hierarchy_value;
}
//main函数文件

hierarchical_mutex high_mutex(1000);
hierarchical_mutex low_mutex(500);
void low_handle();
void high_handle() {
	std::lock_guard lock(high_mutex);
	std::this_thread::sleep_for(std::chrono::microseconds(2000));
	std::cout << "高层次锁任务执行完毕!!" << std::endl;
	low_handle();
}
void thread_a() {
	high_handle();
}

void low_handle() {
	std::lock_guard lock(low_mutex);
	std::this_thread::sleep_for(std::chrono::microseconds(1500));
	std::cout << "低层次锁任务执行完毕!!" << std::endl;
}
void thread_b() {
	hierarchical_mutex now_mutex(100);
	std::lock_guard now_lock(now_mutex);

	high_handle();
}

int main()
{
	std::thread a(thread_a);
	std::thread b(thread_b);
	a.join();
	b.join();
}

hierarchical_mutex 类定义了一个thread_local的变量this_thread_hierarchy_value, 用于存储当前线程正在被锁的那些锁的权重最低的那个。再去声明hierarchical_mutex 对象并lock的时候,需要判断这个对象的权重是不是小于当前线程的权重,如果大于的话抛出异常或者打印到log文件。 thread_a函数是先锁high_mutex,再锁low_mutex,权重由高到低(1000->500),没有问题。 thread_b则是先锁now_mutex再锁high_mutex,最后是low_mutex(100->1000->500),因此check_hierarchy()的时候会出现异常。

运行结果:

C++并发与多线程-使用层次锁防止死锁_第1张图片

你可能感兴趣的:(C++并发与多线程)