C++ 编译器如何保证常量成员变量的线程安全
How c++ compiler guarantees thread safety of constant member variable?
C++ 11x 标准更改了"const"关键字的语义。现在它意味着真正的线程安全。据我了解,常量成员变量等于java最终字段。
我想在 CPU icore 7 G++ 4.7.1 上检查一下。
我编译了以下代码,如 -std=c++0x -pthread -DCONST 和没有。两个可执行文件是相同的。汇编程序版本没有*围栏说明。我希望在构造函数的末尾看到*围栏。
class Big {
public:
#ifdef CONST
const
#endif
long a;
Big(long a) : a(a) {
}
void check()
#ifdef CONST
const
#endif
{
assert(a == 123L);
}
};
int main() {
Big b(123L);
thread t([b] () { b.check(); });
return 0;
}
这更像是一个一般的计算机科学问题,而不是一个代码问题,但这很好,甚至很有趣。
让我们确定一些观点,如果您对这些观点或我随后的推理有任何疑问,请告诉我。 为了清楚起见,我使用"观察"一词来表示"阅读",并修改为表示"写入"。 这不是一个正式的证明。
- 只要没有线程同时
修改该对象,任意数量的线程都可以同时观察某个对象而不会引起争用条件。
const
对象在初始化期间被修改,并且在该对象的生命周期内不会以其他方式修改(我想除了销毁)。初始化在对象的生命周期中只在一个线程中发生一次,然后才能以其他方式修改或观察该对象(从技术上讲,您可以访问未初始化的对象,但是如果您设法完成它,则无论线程安全性如何,很多东西都会被破坏)。
2 和 #3 保证不能同时修改和观察 const 成员,这是规则 #1 的线程安全。
现在。。。 mutable
会改变事情,一旦你开始创建mutable
成员,类编写者就有责任确保使用mutable
成员的const
方法以线程安全的方式处理。
因此,编译器不保证线程安全...但逻辑确实保证了线程安全。 只要const
对象,它的所有mutable
成员都以线程安全的方式处理,并且该对象的所有const
成员都遵守这些规则,就可以保证线程安全。
据我了解,C++11 的变化是,std::
对象以前不能保证运行良好的线程安全 const 成员,我们现在有了这种保证。
视频 Herb Sutter - 你不知道 [空白] 和 [空白] 据我所知,C++11 保证 const == 线程安全的说法的来源,并很好地解释了该声明。
它不是一个直接的同义词。例如,假设你有一个 const 指针:这意味着地址本身是常量,但不一定是它的内容。因此,当由多个线程执行时,任何会修改此变量内容的函数都不被认为是线程安全的。
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 类与私有变量的其他类之间的线程安全性
- 全局变量 多读取器 一个写入器多线程安全?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 成员变量在多线程 C++ 时自行更改
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 多个线程可以安全地同时将相同的值写入同一变量吗?
- C++11:具有互斥锁的线程看到原子变量的值发生变化,尽管这是唯一可以改变它的代码
- C++线程不检测全局变量更改
- 为什么 beginthreadex 线程参数变量在父线程中没有更新
- C++多线程程序:变量定义为类成员的隔离错误
- std::线程不是全局变量,但在到达创建它的函数的末尾时不会超出范围?
- 对全局变量的多线程访问:我应该使用互斥锁吗?
- 子线程中的条件变量等待停止主线程中的执行
- 是局部unordered_map变量线程在C 中安全的线程
- 如何使类静态变量线程安全
- 命名空间中的全局变量 - 线程中的值不同
- 静态变量与堆栈变量:线程安全与堆栈大小
- 共享提升::shared_ptr<>变量线程安全吗?
- 在析构函数中pthead_join()类成员变量线程是否明智?