.NET内存模型,易变量和测试集:什么是保证?
我知道.NET存储器模型(在.NET Framework;不是compact / micro / silverlight / mono / xna / what-have-you-you-you-you-you)保证了某些类型(最引人注目的是基本的整数和引用)操作被保证是原子.
此外,我相信x86 / x64测试和设置指令(和Interlocked.CompareExchange)实际上引用了全局内存位置,所以如果它成功了另一个Interlocked.CompareExchange会看到新的值. 最后,我相信volatile关键字是编译器传播read&写入ASAP并且不重新排序有关此变量的操作(对?). 这导致几个问题: 我的信仰是否正确? 如果有两个全局整数变量x和y,两者都初始化为0,如果我写: x = 1; y = 2; NO线程将看到x = 0和y = 2(即写入将按顺序发生).如果它们是挥发性的,这是否会改变? 解决方法
>只读取和写入最多32位宽的变量(x64系统上为64位宽)为原子.所有这一切意味着你不会读取一个int并获得一个半写的价值.这并不意味着算术是原子的.
>联锁操作也作为内存障碍,所以是的,Interlocked.CompareExchange会看到更新的值. >见 this page. Volatile不意味着订购.一些编译器可能会选择不对易失性变量进行重新排序,但CPU可以自由重新排序.如果要停止CPU重新排序说明,请使用(全)内存屏障. >内存模型确保读写是原子的,并且使用volatile关键字确保读取将始终来自内存而不是来自寄存器.所以你会看到最新的价值.这是因为x86 CPU会在适当时使缓存无效 – 参见 this和 this.另请参见 InterlockedCompareExchange64如何原子读取64位值. 最后,最后一个问题.答案是线程实际上可以看到x = 0和y = 2,并且使用volatile关键字不会改变,因为CPU可以自由地重新排序指令.你需要一个记忆障碍. 概要: >编译器可以自由地重新排序指令.> CPU可以自由重新排序指令.>字大小的读写是原子的.算术和其他操作不是原子的,因为它们涉及读取,计算,然后写入.>从内存读取大小字体将始终检索最新的值.但大多数时候你不知道你是否真的从记忆中读书.>全记忆障碍停止(1)和(2).大多数编译器允许您自己停止(1).> volatile关键字确保你正在从内存中读取 – (4).>互锁操作(锁前缀)允许多个操作是原子的.例如,读写(InterlockedExchange).或者读取比较写(InterlockedCompareExchange).它们也作为记忆障碍,所以(1)和(2)被停止.他们总是写信(显然),所以(4)被保证. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |