Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# volatile作为一种同步机制_C#_Multithreading_Synchronization - Fatal编程技术网

C# volatile作为一种同步机制

C# volatile作为一种同步机制,c#,multithreading,synchronization,C#,Multithreading,Synchronization,假设我有一个类Foo,它有一个名为Count的静态成员变量(类型是integer)。这个变量在多线程应用程序中使用,在对这个变量进行任何读/写操作之前,我使用了锁同步机制。当我阅读这篇文章时,我得到的印象是,我可以移除这个变量周围的所有锁,只需在声明这个变量时使用volatile关键字。这应该能解决所有与同步相关的问题。这是正确的吗?这种方法的优缺点是什么?volatile关键字与锁完全不同。lock意味着有多条语句需要作为一个工作单元以一致的状态执行,例如,如果您希望确保在访问集合中的特定项或

假设我有一个类Foo,它有一个名为Count的静态成员变量(类型是integer)。这个变量在多线程应用程序中使用,在对这个变量进行任何读/写操作之前,我使用了锁同步机制。当我阅读这篇文章时,我得到的印象是,我可以移除这个变量周围的所有锁,只需在声明这个变量时使用volatile关键字。这应该能解决所有与同步相关的问题。这是正确的吗?这种方法的优缺点是什么?

volatile关键字与
锁完全不同。
lock
意味着有多条语句需要作为一个工作单元以一致的状态执行,例如,如果您希望确保在访问集合中的特定项或计算集合中的项时,没有其他线程可以从集合中添加或移除项。
volatile
关键字会影响编译器在从源代码生成机器指令时试图优化代码的行为。编译器可能会以不影响特定代码块的方式对特定代码块中的语句重新排序,但如果变量的值可以从另一个线程更改,则重新排序可能无效。使用<代码> Value告诉编译器不要考虑这些优化,并且总是从内存中读取变量的值,而不是从缓存登记器中读取值。


Jon Skeet在他的文章中对此进行了更详细的讨论。

如果您所做的只是从多个线程读取变量,然后从一个线程写入变量,那么
volatile
可能会工作。但是,如果要在多个线程上更新值(即增加值),则需要某种同步

例如,如果您正在编写以下内容:

Count = Count + 1;
记住,增量需要三个操作:读取、增量、写入。在多个线程上,可能会出现问题。假设
Count
的初始值为零

  • 线程1读取计数(值0)
  • 线程2读取计数(值0)
  • 线程1增加其值(1)
  • 线程1写入计数(值1)
  • 线程2增加其值(1)
  • 线程2写入计数(值1)
Count
的最终值是1,而它应该是2

你想调查一下这个班。特别是,
联锁。增量
联锁。比较交换

我可以移除这个变量周围的所有锁,只需在声明这个变量时使用volatile关键字。这应该能解决所有与同步相关的问题。这是正确的吗

也许吧。也许不是。获得正确的多线程代码是极其困难的。获得低锁多线程代码的正确性最好留给专家

这种方法的优缺点是什么

其优点是,它可以更快几纳秒,以避免锁定。缺点是,如果低锁编程出错,那么程序看起来工作正常,然后出现无法调试或复制的奇怪故障模式

只有在性能分析得出结论,即低锁定解决方案是实现客户要求您达到的性能目标的唯一途径时,您才应该选择低锁定解决方案。只有当你对每一个优化都有了透彻而深刻的理解,你的程序运行的每一个可能的CPU都可以在低锁代码上运行时,你才应该使用低锁解决方案。您需要深入了解CLR为您提供的内存模型、硬件保证的内容以及所有差异


我自己并不具备这种理解力。这就是为什么我除了最琐碎的低锁代码之外什么都不写的原因,我所写的低锁代码都经过了业界领先专家的仔细审查

关于volatile的推荐阅读