“M&M 规则”是否适用于 std::atomic 数据成员?

Does “M&M rule” applies to std::atomic data-member?

”mutable用于指定成员不影响class的外部可见状态(经常用于mutexes,备忘录缓存、惰性评估和访问检测)。" [参考:cv (const and volatile) type qualifiers, mutable specifier]

这句话让我纳闷:

”指南:记住“M&M 规则”:对于成员变量,可变和互斥(或原子)一起使用. [参考:GotW #6a Solution: Const-Correctness, Part 1 (updated for C ++11/14)]

我理解为什么“M&M 规则”适用于 std::mutex 数据成员:允许 const 函数是线程安全的,尽管它们 lock/unlock互斥体数据成员,但“M&M 规则”是否也适用于 std::atomic 数据成员?

你把它弄反了。本文不建议让所有原子成员可变。相反,它说:

(1) For a member variable, mutable implies mutex (or equivalent): A mutable member variable is presumed to be a mutable shared variable and so must be synchronized internally—protected with a mutex, made atomic, or similar.

(2) 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) inside concurrent const member functions.

(2) 表示您希望互斥锁成员可变。因为通常您还想在 const 方法中锁定互斥锁。 (2) 没有提到原子成员。

(1) 另一方面说,如果一个成员是可变的,那么你需要在内部处理同步,无论是通过互斥体还是通过使成员成为 atomic。那是因为之前文章提到的子弹:

If you are implementing a type, unless you know objects of the type can never be shared (which is generally impossible), this means that each of your const member functions must be either:

  • truly physically/bitwise const with respect to this object, meaning that they perform no writes to the object’s data; or else
  • internally synchronized so that if it does perform any actual writes to the object’s data, that data is correctly protected with a mutex or equivalent (or if appropriate are atomic<>) so that any possible concurrent const accesses by multiple callers can’t tell the difference.

可变成员不是“真正的常量”,因此您需要在内部处理同步(通过互斥锁或使成员成为原子成员)。

TL;DR:这篇文章并不建议让所有原子成员都可变。它更建议使互斥锁成员可变并对所有可变成员使用内部同步。