#include <thread>
#include <list>
#include <mutex>
#include <algorithm>
#include <stack>
#include <exception>
#include <memory>
#include <iostream>
class hierarchical_mutex {
private:
    std::mutex internal_mutex;
    unsigned long const hierarchy_value;
    unsigned long previous_hierarchy_value;
    static thread_local unsigned long this_thread_hierarchy_value;

    // 若要对一个mutex加锁,后面mutex的层级必须低于前面已经被锁定的mutex的层级
    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() {
        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;
    }
};
// 初始化当前线程的层级编号为ul的最大值,所以最开始任意的hierarchical_mutex都可以被加锁。
// 由于声明为thread_local 所以每个线程都具备自己的this_thread_hierarchy_value副本
thread_local unsigned long hierarchical_mutex::this_thread_hierarchy_value(ULONG_MAX);

// 使用层级锁防范死锁
// 设置层级 层级越低编号越小
hierarchical_mutex high_level_mutex(10000);
hierarchical_mutex low_level_mutex(5000);
hierarchical_mutex other_mutex(6000);

int do_low_level_stuff() {
    std::cout << "0" << std::endl;
    return 1;
};
int low_level_func() {      // 最底层级
    std::lock_guard<hierarchical_mutex> lock(low_level_mutex);
    return do_low_level_stuff();
}

int do_high_level_stuff(int some) {
    std::cout << some << std::endl;
    return some+1;
}
int high_level_func() {     // 先对high_level_mutex加锁再对low_level_mutex加锁,符合加锁规则
    std::lock_guard<hierarchical_mutex> lock(high_level_mutex);
    auto res = do_high_level_stuff(low_level_func());
    return res;
}

void thread_a() {   // 线程a逻辑正确
    high_level_func();
}

void do_other_stuff() {
    std::cout << "other" << std::endl;
}

void other_stuff() {
    high_level_func();
    do_other_stuff();
}

void thread_b() {   // 先对中间层级加锁,再调用高层级函数,违反了层级规则,报错。
    std::lock_guard<hierarchical_mutex> lock(other_mutex);
    other_stuff();
}

int main() {
    auto t1 = std::thread(thread_a);
    t1.join();
    auto t2 = std::thread(thread_b);
    t2.join();
    return 0;
}

try_lock使用:

lock函数也可以在内部利用该函数,预防死锁。