关于c#:DateTime可以在64位环境中撕裂吗?

Can DateTime tear in a 64 bit environment?

在C中,只要变量的大小最多为native int(即32位运行时环境中的4个字节,64位环境中的8个字节),那么为变量设置值就是原子的。在包含所有引用类型和大多数内置值类型(byteshortintlong等)的64位环境中。

设置一个更大的值不是原子的,并且在只有部分内存被更新的地方会导致撕裂。

DateTime是一个结构,它只包含一个包含所有数据(TicksDateTimeKind的单个ulong字段,ulong本身在64位环境中是原子的。

这是否意味着DateTime也是原子的?或者下面的代码会在某个时刻导致撕裂吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static DateTime _value;
static void Main()
{
    for (int i = 0; i < 10; i++)
    {
        new Thread(_ =>
        {
            var random = new Random();
            while (true)
            {
                _value = new DateTime((long)random.Next() << 30 | (long)random.Next());
            }
        }).Start();
    }

    Console.ReadLine();
}


From the ECMA specification section"I.12.6.6 Atomic reads and writes"

A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size (the size of type native int) is atomic (see §I.12.6.2) when all the write accesses to a location are the same size. Atomic writes shall alter no bits other than those written. Unless explicit layout control (see Partition II (Controlling Instance Layout)) is used to alter the default behavior, data elements no larger than the natural word size (the size of a native int) shall be properly aligned. Object references shall be treated as though they are stored in the native word size.

这是一个EDOCX1。

So long as sizeof(IntPtr) >= sizeof(DateTime)is true for the runtime environment(AKA:running as 64 bit),and they don't alter the internal structure to be explicited layout with mislained bytes instead of the [StructLayout(LayoutKind.Auto)]it currently has,then reads and writes of a DateTimeECMA规范

在64位环境中运行以下代码是可以核查的:

1
2
3
4
5
6
public unsafe static void Main()
{
    Console.WriteLine(sizeof(DateTime)); // Outputs 8
    Console.WriteLine(sizeof(IntPtr)); // Outputs 8
    Console.WriteLine(sizeof(ulong)); // Outputs 8
}


运行一些测试,并以用户回答为基础,很安全地说它今天是原子。

我写了一份测试,以确定在X个项目中,在NT64、Datetime和3个128、192和256 sizes-none的定制结构中,能找到多少泪水。

The test consists of:

  • 将一组数值添加到一个阵列,因此它们是众所周知的。
  • 为每个阵列位置设置一个螺纹,该螺纹将指定从阵列到共享变量的值。
  • Setting up the same number of threads(array.length)to read from this shared variable to a local.
  • 检查这地方是否包含在原始阵列中。
  • The results are as follows in my machine(Core I7-4500U,Windows 10 X64,Net 4.6,release without debug,Platform target:X64 with code optimization):

    ZZU1

    测试代码可以在这里找到:https://gist.github.com/flash3001/da5bd3ca800f674082d8030EF70CF4


    语言规范。

    BLCK1/