"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.
链接的文章有很多代码示例和进一步的阐述,如果你想深入研究的话。
在许多情况下,可以指定许多成员函数 '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 concurrentconst
member functions.
链接的文章有很多代码示例和进一步的阐述,如果你想深入研究的话。