"correct" 指定 class-member mutex 'mutable' 是为了更多的 'const' 成员函数吗?

Is it "correct" to specify class-member mutex 'mutable' for the purpose of much-more 'const' member functions?

在许多情况下,可以指定许多成员函数 'const' - 它们不会修改 class 的任何数据成员......几乎:它们会 lock/unlock class 互斥体。 在这种情况下,指定互斥体 'mutable' 是一个好习惯吗? ...否则,将无法指定 get_a (), get_b(), get_c(), get_d() 'const'.

--

一个仅仅是的例子。假设 'example' 是线程安全的 class 并且 m_mutex 保护其共享资源 get_a(), get_b(), get_c(), get_d() 不修改:

#include <mutex>

class example
{
public:
    size_t get_a(void) const {
        std::lock_guard lck(m_mutex);
        return m_str.length() + a;
    };

    size_t get_b(void) const {
        std::lock_guard lck(m_mutex);
        return m_str.length() * 2 + a + b;
    };

    size_t get_c(void) const {
        std::lock_guard lck(m_mutex);
        return m_str.length() * 4 + a + b;
    };

    size_t get_d(void) const {
        std::lock_guard lck(m_mutex);
        return m_str.length() * 8 + a;
    };

    void modify_something() {
        std::lock_guard lck(m_mutex);
        if (m_str.length() < 1000) {
            m_str.append(".");
            a++;
            b++;
        }
    };

protected:
    mutable std::mutex m_mutex;
    std::string m_str;
    int a = 0, b = 0;
};

是的,正是出于这个原因,使同步对象可变是很常见的。话虽如此,将那些同步对象保存在 class 中也相对不常见,因为“确保安全并发”很少是 class 本身 about.

这不仅是正确的,而且是标准做法。成员 mutex 被描述为“非可观察的非常量”,这意味着它对“用户”观察者表现为常量。

Herb Sutter 推广了 M&M rule:

For a member variable, mutable and mutex (or atomic) go together.

与您的问题相关的规则部分指出:

For a member variable, mutex (or similar synchronization type) implies mutable: A member variable that is itself of a synchronization type, such as a mutex or a condition variable, naturally wants to be mutable, because you will want to use it in a non-const way (e.g., take a std::lock_guard<mutex>) inside concurrent const member functions.

链接的文章有很多代码示例和进一步的阐述,如果你想深入研究的话。