c/c++ 多线程 层级锁
程序员文章站
2022-05-25 16:59:32
多线程 层级锁 当要同时操作2个对象时,就需要同时锁定这2个对象,而不是先锁定一个,然后再锁定另一个。同时锁定多个对象的方法:std::lock(对象1.锁,对象2.锁...) 但是,有的时候,并不能同时得到所有要锁定的锁,必须是先锁定某个后,再锁定其他的,这种情况就不能使用std::lock函数了 ......
多线程 层级锁
当要同时操作2个对象时,就需要同时锁定这2个对象,而不是先锁定一个,然后再锁定另一个。同时锁定多个对象的方法:std::lock(对象1.锁,对象2.锁...)
但是,有的时候,并不能同时得到所有要锁定的锁,必须是先锁定某个后,再锁定其他的,这种情况就不能使用std::lock函数了,怎么办呢,使用有顺序的锁。
额外说明:lock_guard<模板类> ,中模板类的实现。这个模板类只要实现mutex所需要的三个成员函数即可:lock(), unlock(), try_lock()。
例子:lock_guard的模板类hierarchical_mutex
class hierarchical_mutex{ std::mutex mtx; unsigned long const hcl_val; unsigned long pre_hcl_val; static thread_local unsigned long this_hcl_val; void check_for_hcl_violaction(){ if(this_hcl_val <= hcl_val){ throw std::logic_error("mutex hierarchy violated"); } } void update_hierarchy_value(){ pre_hcl_val = this_hcl_val; this_hcl_val = hcl_val; } public: explicit hierarchical_mutex(unsigned long val): hcl_val(val), pre_hcl_val(0){} void lock(){ check_for_hcl_violaction(); mtx.lock(); update_hierarchy_value(); } void unlock(){ this_hcl_val = pre_hcl_val; mtx.unlock(); } bool try_lock(){ check_for_hcl_violaction(); if(!mtx.try_lock()) return false; update_hierarchy_value(); return true; } };
顺序锁的应用例子:当要锁定时某个锁时,要先检查已经上锁的锁的序号,如果序号低于现在要锁的锁的序号的话就可以锁定,否则,抛出异常。
我也没理解锁的序号的真正含义,只是做个记录,抄一个例子。。。
#include <mutex> #include <climits>//ulong_max #include <thread> class hierarchical_mutex{ std::mutex mtx; unsigned long const hcl_val; unsigned long pre_hcl_val; static thread_local unsigned long this_hcl_val; void check_for_hcl_violaction(){ if(this_hcl_val <= hcl_val){ throw std::logic_error("mutex hierarchy violated"); } } void update_hierarchy_value(){ pre_hcl_val = this_hcl_val; this_hcl_val = hcl_val; } public: explicit hierarchical_mutex(unsigned long val): hcl_val(val), pre_hcl_val(0){} void lock(){ check_for_hcl_violaction(); mtx.lock(); update_hierarchy_value(); } void unlock(){ this_hcl_val = pre_hcl_val; mtx.unlock(); } bool try_lock(){ check_for_hcl_violaction(); if(!mtx.try_lock()) return false; update_hierarchy_value(); return true; } }; thread_local unsigned long hierarchical_mutex::this_hcl_val(ulong_max); hierarchical_mutex high_level_mutex(10000); hierarchical_mutex low_level_mutex(5000); int do_low_level_stuff(){ return 1; } int low_level_func(){ std::lock_guard<hierarchical_mutex> lk(low_level_mutex); return do_low_level_stuff(); } void high_level_stuff(int param){ } void high_level_func(){ std::lock_guard<hierarchical_mutex> lk(high_level_mutex); high_level_stuff(low_level_func()); } void thread_a(){ high_level_func(); } hierarchical_mutex other_mutex(100); void do_other_stuff(){ } void other_stuff(){ high_level_func(); do_other_stuff(); } void thread_b(){ std::lock_guard<hierarchical_mutex> lk(other_mutex); other_stuff(); } int main(){ //锁定顺序合法(因为先锁的大的,后锁的小的) std::thread a(thread_a); //锁定顺序非法(因为先锁的小的,后锁的大的) std::thread b(thread_b); a.join(); b.join(); }