gpt4 book ai didi

c# - Array.Copy 是否保证基于每个元素的原子读写?

转载 作者:太空狗 更新时间:2023-10-29 22:29:42 25 4
gpt4 key购买 nike

C# 确保 certain types always have atomic reads and writes .我调用 Array.Copy 时是否有同样的保证?在那些类型的两个数组上?每个元素都是原子读写的吗?我浏览了一些 the source code但并没有给出可靠的答案。

例如,如果我滚动自己的代码来复制两个数组...

static void Copy<T>(T[] source, T[] destination, int length)
{
for (int i = 0; i < length; ++i)
destination[i] = source[i];
}

... 并调用了 Copy<int>变体,这保证了每个元素都是从 source 中自动读取的并自动写入 destination因为 C# promise int读取和写入是原子的。我只是问是否 Array.Copy保持这种保证(而不是,比如说,使用它自己的专用内存块复制例程可能会破坏这种保证)。

最佳答案

Array.Copy() 尝试通过使用 memmove() CRT 函数来提高复制效率,这是一种原始的内存到内存复制,而不考虑存储在数组中的实际类型。如果数组元素类型小于自然处理器字长,效率会大大提高。

所以你需要知道 memmove() 是否可以提供原子性保证。这是 CLR 程序员明确回答的棘手问题。原子性是对象引用的基本特征,当垃圾收集器不能以原子方式更新这些引用时,它就无法正确运行。所以程序员在 CLR 代码中对此进行特殊处理,comment he provided告诉你你想知道的(编辑以适合):

// The CRT version of memmove does not always guarantee that updates of 
// aligned fields stay atomic (e.g. it is using "rep movsb" in some cases).
// Type safety guarantees and background GC scanning requires object
// references in GC heap to be updated atomically.

那是一种非常悲观的人生观。但显然不,当 CLR 作者没有做出这种假设时,您不能假设 Array.Copy() 是原子的。


也许需要以实际考虑为准。在相当常见的架构上,x86 和 x64 有一个 memmove() 实现,不会使 CLR 内存模型保证更糟,它们一次复制 4 或 8 个对齐的字节。实际上,通用代码替代中的 for 循环不能保证是原子的,因为 T 不能保证是原子的。

最实用的是你不应该问这个问题。仅当您有另一个线程在没有任何同步的情况下访问数组时,原子性才重要。写入源数组或从目标数组读取。然而,这是有保证的线程竞争。写入源数组是最糟糕的,副本具有新旧数据的任意混合。从目标数组读取随机产生陈旧数据,就像线程错误通常那样。您必须非常勇敢地冒险编写此类代码。

关于c# - Array.Copy 是否保证基于每个元素的原子读写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51343209/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com