C++ Concurrent in Action(英文版)书上(No.52-No.53)写的hierarchical_mutex函数,只适合结合std::lock_guard使用,直接使用如果不考虑顺序,可能会出现问题。
参看hierarchical_mutex类的代码:
#include <mutex> class hierarchical_mutex { 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; } public: explicit hierarchical_mutex(unsigned long value) : hierarchy_value(value), previous_hierarchy_value(0) {} void lock() { check_for_hierarchy_violation(); internal_mutex.lock(); update_hierarchy_value(); } void unlock() { 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; } static unsigned long get_thread_hierarchy_value() { return this_thread_hierarchy_value; } }; thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value(ULONG_MAX);
测试代码:
#include <iostream> #include "hierarchical_mutex.h" hierarchical_mutex m1(10000); hierarchical_mutex m2(2000); hierarchical_mutex m3(1000); hierarchical_mutex m4(100); int main() { m1.lock(); m2.lock(); m3.lock(); m4.lock(); m1.unlock(); m2.unlock(); m3.unlock(); m4.unlock(); std::cout << "hierarchy value: " << hierarchical_mutex::get_thread_hierarchy_value() << std::endl; }
正确时,输出值应该为(unsigned long)(-1),该测试结果输出值为1000。
如果打算使用上述的类,建议修改unlock函数如下所示:
void unlock() { if (this_thread_hierarchy_value != hierarchy_value) { throw std::logic_error("mutex unlock hierarchy violated"); } this_thread_hierarchy_value = previous_hierarchy_value; internal_mutex.unlock(); }
希望给看C++ Concurrent in Action一点提示。