Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用c语言再现十进制数的读取_C#_Atomic_Lock Free - Fatal编程技术网

C# 用c语言再现十进制数的读取

C# 用c语言再现十进制数的读取,c#,atomic,lock-free,C#,Atomic,Lock Free,眼见为实。有人能复制一个读取小数点的程序吗?我尝试旋转多个线程,在1和2之间更改相同的十进制数。我没有发现任何与1或2不同的读数 void TornDecimalReadTest() { decimal sharedDecimal = 1; int threadCount = 100; var threads = new List<Thread>(); for (int i = 0; i < thread

眼见为实。有人能复制一个读取小数点的程序吗?我尝试旋转多个线程,在1和2之间更改相同的十进制数。我没有发现任何与1或2不同的读数

void TornDecimalReadTest()
    {
        decimal sharedDecimal = 1;
        int threadCount = 100;
        var threads = new List<Thread>();

        for (int i = 0; i < threadCount; i++)
        {
            int threadId = i;
            var thread = new Thread(() =>
            {
                Thread.Sleep(5000);

                decimal newValue = threadId % 2 == 0 ? 1 : 2;
                bool isWriterThread = threadId % 2 == 0;

                Console.WriteLine("Writer : " + isWriterThread + " - will set value " + newValue);

                for (int j = 0; j < 1000000; j++)
                {
                    if (isWriterThread)
                        sharedDecimal = newValue;

                    decimal decimalRead = sharedDecimal;

                    if (decimalRead != 1 && decimalRead != 2)
                        Console.WriteLine(decimalRead);
                }
            });

            threads.Add(thread);
        }

        threads.ForEach(x => x.Start());
        threads.ForEach(x => x.Join());
    }
编辑:我希望读线程看不到写线程的原子变化,因此值应该不同于1或2

void TornDecimalReadTest()
    {
        decimal sharedDecimal = 1;
        int threadCount = 100;
        var threads = new List<Thread>();

        for (int i = 0; i < threadCount; i++)
        {
            int threadId = i;
            var thread = new Thread(() =>
            {
                Thread.Sleep(5000);

                decimal newValue = threadId % 2 == 0 ? 1 : 2;
                bool isWriterThread = threadId % 2 == 0;

                Console.WriteLine("Writer : " + isWriterThread + " - will set value " + newValue);

                for (int j = 0; j < 1000000; j++)
                {
                    if (isWriterThread)
                        sharedDecimal = newValue;

                    decimal decimalRead = sharedDecimal;

                    if (decimalRead != 1 && decimalRead != 2)
                        Console.WriteLine(decimalRead);
                }
            });

            threads.Add(thread);
        }

        threads.ForEach(x => x.Start());
        threads.ForEach(x => x.Join());
    }

此代码将演示十进制数的读取:

它在发布版本中发生的速度比调试版本快

我认为您在测试代码中没有看到撕裂读取的原因是因为您只更改了0和1之间的值。测试期间更改的位很可能都在用于内部存储值的同一个字中,并且对字的访问是原子的


通过在1和1000000000之间更改值,我们强制位在两个不同的字中更改,从而允许观察到撕裂读取。

此代码将演示十进制的撕裂读取:

它在发布版本中发生的速度比调试版本快

我认为您在测试代码中没有看到撕裂读取的原因是因为您只更改了0和1之间的值。测试期间更改的位很可能都在用于内部存储值的同一个字中,并且对字的访问是原子的



通过在1和1000000000之间更改值,我们强制位在两个不同的字中更改,从而允许观察到撕裂的读取。

什么是撕裂的十进制数?您有一些源代码与我们共享吗?我知道他的意思。他所说的是读取损坏,当一个线程中更新了一个没有原子读/写操作的值类型,而另一个线程正在读取它时,会发生这种情况,从而导致值损坏。我建议您选择两个十进制数0M和decimal.MaxValue。让线程不断地读写这些值,看看你是否在读的时候得到了一个撕裂的值。1M和2M的问题是,它们的位除了最低的字节外是相同的,因此它们永远不会得到一个撕裂的值,因为大多数字节都是0。另外,看看这篇msdn文章,它有一个关于读/写撕裂的示例:什么是撕裂的十进制数?你有一些源代码与我们分享吗?我知道他的意思。他所说的是读取损坏,当一个线程中更新了一个没有原子读/写操作的值类型,而另一个线程正在读取它时,会发生这种情况,从而导致值损坏。我建议您选择两个十进制数0M和decimal.MaxValue。让线程不断地读写这些值,看看你是否在读的时候得到了一个撕裂的值。1M和2M的问题是,它们的位除了最低的字节外都是相同的,因此它们永远不会得到一个被撕碎的值,因为大多数字节都是0。也请查看这篇msdn文章,它有一个关于读/写撕裂的示例:我刚刚用Int64和0x0000000000000000和0xFFFFFFFFFFFFFF值尝试了相同的实验,但也无法重新生成撕裂。我可以使用0x1234567890ABCDEF和0xFEDCBA0987654321。这也是因为单词是原子的吗?@BanksySan是的,当运行64位代码时,64位整数值的读写是原子的。@MatthewWatson就是这样。“如果增强32位模式,它应该可以工作。”马修沃森刚刚测试过它。如果我将/platform:x86开关添加到编译器中,那么测试就可以运行了!我刚刚用Int64和0x0000000000000000和0xFFFFFFFFFFFFFFFF的值做了同样的实验,但也无法恢复撕裂。我可以使用0x1234567890ABCDEF和0xFEDCBA0987654321。这也是因为单词是原子的吗?@BanksySan是的,当运行64位代码时,64位整数值的读写是原子的。@MatthewWatson就是这样。“如果增强32位模式,它应该可以工作。”马修沃森刚刚测试过它。如果我将/platform:x86开关添加到编译器中,那么测试就可以运行了!