当你有一个
long[] myArray = new long[256];
其项目由多个线程使用更改
Interlocked.Increment(ref myArray[x])
肯定无法获得快照myArray
在某个时间点,由于有非锁定写入同时进行,所以我不想得到这一点。
那么我真的必须这样做吗Volatile.Read
像这样的每个元素都可以获取过去某个时刻所有值的副本?
long[] copy = new long[256];
for (int i = 0; i < 256; i++)
copy[i] = Volatile.Read(ref myArray[i]);
由于我对某个时间点的快照不感兴趣,过时的值不是问题,但由于 64 位非易失性读取不是原子的,我担心以下内容可能会给我预增量一半long 和后增量 half,这可能会给出数组中从未存在的值。
long[] copy = new long[256];
for (int i = 0; i < 256; i++)
copy[i] = myArray[i];
也是如此Volatile.Read
鉴于我不想使用任何锁定,变体是正确的选择吗?
如果过时的值对您来说不是问题,并且您需要的只是原子读取(不是有序读取),那么在 x64 上您可以只使用纯读取而不是Volatile.Read
。
它在 ARM 系统上非常有用,因为易失性读/写是相当重量级的,因为它们是使用 DMB 实现的。
重要的根据this https://stackoverflow.com/a/52959366 and that https://stackoverflow.com/a/9741597,您需要在 64 位模式下(构建并)运行 .Net 程序才能正常工作:
如果您在 64 位操作系统上运行 C# 代码
然后,CLR 版本读取和写入 64 位双精度数和长整型数
整数也保证是原子的
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)