• 层级锁笔记


    注意看test_hierarchy_lock函数:如果thread t2的不注释,就会报错。

    这是因为层级锁 更强调单个线程内上锁的顺序。
    线程t2已经获取了hmtx2,再试图获取hmtx1就会因为违反层级顺序而抛出异常

    #include 
    #include 
    //层级锁
    class hierarchical_mutex {
    public:
    	explicit hierarchical_mutex(unsigned long value) :_hierarchy_value(value),
    	_previous_hierarchy_value(0) {}
    	hierarchical_mutex(const hierarchical_mutex&) = delete;
    	hierarchical_mutex& operator=(const hierarchical_mutex&) = delete;
    	void lock() {
    		check_for_hierarchy_violation(); // 必须_this_thread_hierarchy_value >= 待获取锁的层级值 当前层级值,才继续
    		_internal_mutex.lock();
    		update_hierarchy_value(); // _this_thread_hierarchy_value 变成 待获取锁的层级值
    	}
    	void unlock() {
    		if (_this_thread_hierarchy_value != _hierarchy_value) {
    			throw std::logic_error("mutex hierarchy violated");
    		}
    		_this_thread_hierarchy_value = _previous_hierarchy_value;
    		_internal_mutex.unlock();
    	}
    	bool try_lock() {
    		check_for_hierarchy_violation();
    		if (!_internal_mutex.try_lock()) {
    			return false;
    		}
    		update_hierarchy_value();
    		return true;
    	}
    private:
    	std::mutex  _internal_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;
    	}
    };
    
    thread_local unsigned long hierarchical_mutex::_this_thread_hierarchy_value(ULONG_MAX);
    
    void test_hierarchy_lock() {
    	hierarchical_mutex  hmtx1(1000);
    	hierarchical_mutex  hmtx2(500);
    	std::thread t1([&hmtx1, &hmtx2]() {
    		std::this_thread::sleep_for(std::chrono::milliseconds(500));
    		hmtx1.lock();
    		hmtx2.lock();
    		hmtx2.unlock();
    		hmtx1.unlock();
    		});
    	std::thread t2([&hmtx1, &hmtx2]() {
    		hmtx2.lock();
    //		hmtx1.lock();
    //		hmtx1.unlock();
    		hmtx2.unlock();
    		});
    	t1.join();
    	t2.join();
    }
    
    int main(){
    	test_hierarchy_lock();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
  • 相关阅读:
    HTML轮播图 页脚问题 急!
    基于SSM的高校毕业设计选题管理系统(有报告)。Javaee项目。
    【C++】队列
    Rust GUI库 egui 的简单应用
    中秋假期,回不了家的程序员,竟然用Python做了这件事...
    【web-避开客户端控件】(2.1.1)客户端传输数据:隐藏表单字段、HTTP cookie、URL参数
    网络编程套接字,Linux下实现echo服务器和客户端
    MQ刷盘机制
    热门开源项目OpenHarmony
    聊聊Spring的Aware接口
  • 原文地址:https://blog.csdn.net/qq_34529292/article/details/136425219