hierarchical_mutex函数问题(C++ Concurrent in Action)

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一点提示。

原文地址:https://www.cnblogs.com/albizzia/p/8595843.html