指针地址交换始终是C中的原子操作吗?
关于这个问题
Is there cases where a 32-bit variable could not been properly-aligned和提供的答案,我可以假设我可以在Windows平台下工作时交换地址而没有任何副作用吗?
例如: struct Foo { // whatever Foo can hold }; struct Bar { void buildFoo() { auto tmp = new Foo; // do some stuff on tmp,or not foo = tmp; } Foo* foo; }; 现在,让一些线程通过一个Bar实例使用foo,以及调用Bar :: buildFoo()的其他线程有什么后果? 解决方法
C标准
不,同时修改/访问raw2指针不能保证是c中的原子操作. C标准表示如果一个线程修改内存位置而另一个线程修改/访问相同的内存位置,则存在数据争用,如果存在这样的数据争用,则程序会受到未定义的行为的影响.
1. raw未包含在std :: atomic< Foo *>或等效物中. 特定于实现的行为(Windows 32/64位) 在Windows下,它保证对正确对齐的32位变量的读/写始终是原子的,正如您之前引用的question/answer链接的the article所述. 在64位窗口上访问正确对齐的64位变量也是原子的.
这是什么意思? 标准说了一件事,而微软的文档说另一个……我们要信任和合作?这当然取决于我们在做什么. 如果我们正在为Windows平台开发soley,我们可以阅读所使用的编译器在代码生成方面所保证的内容并从那里开始,但是如果我们想要编写可能在不同平台下编译和运行的代码,那么唯一要做的就是正确信任是标准. 所以在windows下工作时我可以安全地交换32位变量吗? 如果你通过“交换”意味着一个操作,如下面的代码片段中写的内容,答案是否,但如果你的意思是“分配”答案是肯定的. void swap (int& a,int& b) { int tmp = a; a = b; b = tmp; } int main () { int x = 1; int y = 2; swap (x,y); } 上面的代码片段(或前面提到的文档)中没有任何内容表明这将是一个原子操作,当查看我们的交换实现时,我们很容易看到操作未正确同步. 在Windows下读取/写入单个32位变量是安全的,但是在上面没有什么可以保证当我们处于交换中间时x和y都没有值2. 但是,保证x永远不会包含前一个x中50%的字节和y中50%的字节,或类似的..个别写入是原子的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |