提问人:Amit 提问时间:3/28/2022 最后编辑:Amit 更新时间:3/28/2022 访问量:340
“M&M 规则”是否适用于 std::atomic data-member?
Does “M&M rule” applies to std::atomic data-member?
问:
“Mutable 用于指定成员不影响类的外部可见状态(通常用于互斥锁、备忘录缓存、延迟评估和访问检测)。”[参考:cv(常量和易失性)类型限定符,可变说明符]
这句话让我感到疑惑:
“指南:记住”M&M规则“:对于成员变量,可变和互斥(或原子)一起。[参考:GotW #6a 解决方案:常量正确性,第 1 部分(已于 C++11 月 14 日更新)]
我理解为什么“M&M 规则”适用于 data-member:允许 const-functions 是线程安全的,尽管它们锁定/解锁互斥数据成员,但“M&M 规则”是否也适用于 data-member?std::mutex
std::atomic
答:
你把它部分倒退了。本文并不建议使所有原子成员都可变。相反,它说:
(1) 对于成员变量,可变意味着互斥(或等效):A 可变成员变量被假定为可变共享变量 因此必须在内部同步 - 使用互斥锁进行保护,使 原子的,或类似的。
(2) 对于成员变量,互斥锁(或类似的同步类型) means mutable:一个成员变量,它本身就是一个同步 类型,例如互斥锁或条件变量,自然希望是 可变的,因为您将希望以非常规的方式使用它(例如, 在并发 const 成员中获取 std::lock_guard) 功能。
(2) 表示您希望互斥成员可变。因为通常您还希望在方法中锁定互斥锁。(2)没有提到原子成员。const
(1) 另一方面说,如果一个成员是可变的,那么你需要在内部处理同步,无论是通过互斥锁还是通过使成员成为 .那是因为文章之前提到的项目符号:atomic
如果要实现一个类型,除非您知道该类型的对象永远不能共享(这通常是不可能的),这意味着每个 const 成员函数必须是:
- 对于此对象,真正的物理/位常量,这意味着它们不对对象的数据执行任何写入;否则
- 内部同步,以便如果它确实对对象的数据执行任何实际写入,则该数据将使用互斥锁或等效项(或者,如果适用是原子<>)正确保护,以便多个调用方的任何可能的并发常量访问都无法区分。
可变的成员不是“真正的常量”,因此您需要在内部处理同步(通过互斥锁或使成员成为原子)。
TL;DR:这篇文章并不建议让所有的原子成员都是可变的。相反,它建议使互斥成员可变,并对所有可变成员使用内部同步。
评论