And*_*rew 5 c++ race-condition undefined-behavior
假设我定义了一个以下的C++对象:
class AClass
{
public:
AClass() : foo(0) {}
uint32_t getFoo() { return foo; }
void changeFoo() { foo = 5; }
private:
uint32_t foo;
} aObject;
Run Code Online (Sandbox Code Playgroud)
该对象由两个线程T1和T2共享.T1经常getFoo()在循环中调用以获得一个数字(如果changeFoo()以前没有被调用,它将始终为0 ).在某些时候,T2调用changeFoo()它来改变它(没有任何线程同步).
是否有任何实际的机会有史以来T1获得的值会有所不同比0或5 的现代计算机体系结构和编译器?到目前为止我调查的所有汇编代码都使用32位内存读写,这似乎可以节省操作的完整性.
其他原始类型呢?
实际意味着您可以提供现有体系结构或符合标准的编译器的示例,其中理论上可以实现此(或具有不同代码的类似情况).我把" 现代"这个词留下了一点主观.
编辑:我可以看到很多人注意到我不应该期待5被读.这对我来说完全没问题,我没有说我这么做(虽然感谢你指出这方面的问题).我的问题更多的是关于上述代码可能发生什么样的数据完整性违规.
Mat*_* M. 10
在实践中,你不会看到任何其他东西,0或者5据我所知(也许是一些奇怪的16位架构,32位int,而事实并非如此).
但是,你是否真的看到5了并不能保证.
假设我是编译器.
我知道了:
while (aObject.getFoo() == 0) {
printf("Sleeping");
sleep(1);
}
Run Code Online (Sandbox Code Playgroud)
我知道:
printf 不能变 aObjectsleep 不能变 aObjectgetFoo不会改变aObject(谢谢内联定义)因此我可以安全地转换代码:
while (true) {
printf("Sleeping");
sleep(1);
}
Run Code Online (Sandbox Code Playgroud)
因为根据C++标准aObject,在此循环期间没有其他人访问.
这就是未定义的行为意味着什么:炸毁了预期.
实际上,所有主流 32 位架构都以原子方式执行 32 位读写。除了 0 或 5 之外,你永远不会看到任何东西。
| 归档时间: |
|
| 查看次数: |
747 次 |
| 最近记录: |