Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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#_Interlocked Increment - Fatal编程技术网

C# 联锁增量和锁定的用法混乱

C# 联锁增量和锁定的用法混乱,c#,interlocked-increment,C#,Interlocked Increment,我了解联锁.增量和lock()的功能。但我不知道什么时候该用一个或另一个。据我所知,Interlocked.Increment增加共享的int/long值,而Aslock()用于锁定代码区域 例如,如果我想更新字符串值,可以使用lock(): 但是,这在联锁类中是不可能的 为什么不能通过互锁的来实现这一点 这些同步机制之间有什么区别 联锁。增量可以而且应该用于增加共享int变量。 在功能上使用联锁。增量与: lock(_object) { counter++; } 但是是互锁的。增量在

我了解
联锁.增量
lock()
的功能。但我不知道什么时候该用一个或另一个。据我所知,
Interlocked.Increment
增加共享的int/long值,而As
lock()
用于锁定代码区域

例如,如果我想更新字符串值,可以使用
lock()

但是,这在
联锁
类中是不可能的

  • 为什么不能通过互锁的
    来实现这一点
  • 这些同步机制之间有什么区别

联锁。增量可以而且应该用于增加共享
int
变量。 在功能上使用
联锁。增量
与:

lock(_object)
{
   counter++;
}

但是
是互锁的。增量
在性能方面要便宜得多。

如果要交换参考值,并在原子操作中返回原始值,可以使用<代码>互锁。递增
完全按照它所说的那样:递增一个数字


但在.NET中,简单地为变量或任何32位值类型分配一个引用值都是原子的。我能想到的另一种情况是,如果您创建一个压缩结构并设置属性,这将迫使编译器不以4字节边界对齐成员(但这并不是您经常做的事情),则后者不适用.

互锁。增量
和相关方法依靠硬件指令对单个32位或64位内存值执行同步修改,确保访问相同值的多个线程不会读取/写入过时数据。这是必要的,因为在硬件级别,处理器具有内存值的本地/总线副本(为了性能,通常称为总线内存或cpu缓存)

lock(){}
对一段代码而不是单个整数值执行同步。结果代码不是依赖硬件指令来同步对变量的访问,而是依赖操作系统同步原语(软件,而不是硬件)来保护内存和代码执行

此外,lock()的使用会产生内存障碍,确保从多个CPU访问相同的变量会产生同步(非陈旧)数据。这在其他语言/平台中是不正确的,在这些语言/平台中,必须显式执行内存障碍和隔离

对整数值使用
互锁
方法更有效,因为硬件具有执行必要同步的本机支持。但是这种硬件支持只存在于诸如_int32和_int64之类的本机积分,因为硬件没有更高级复杂类型的概念,
联锁
类型中没有公开这样的高级方法。因此,您不能使用
Interlocked
来同步
System.String
或任何
System.Object
派生类型的分配

(如果您使用的是较低级别的语言,即使可以使用相同的硬件指令来完成对字符串值的指针赋值,但事实上在.NET中字符串对象并不表示为指针,因此在任何“纯”语言中都不可能这样做。)NET语言。我正在避免这样一个事实,即如果您真的想要,您可以使用不安全的方法解析指针并执行字符串值的联锁赋值,但我觉得这不是您真正想问的,而且联锁不支持这一点,因为需要在引擎盖下进行GC固定,这可能会与使用
lock()


因此,对于“引用类型”的同步修改/分配,您需要使用同步原语(即lock(){}、Monitor等)。如果需要同步的只是一个整数值(Int32、Int64),那么使用互锁方法会更有效。如果有多个整数值需要同步,则使用lock()语句可能仍然有意义,例如递增一个整数,同时递减第二个整数,这两个整数都需要作为单个逻辑操作进行同步。

也许这篇博文会有所帮助:“但是,
是互锁的。增量
在性能方面要便宜得多。“为什么它的背后是一样的呢?”纪尧姆不,它们不一样,我说它们在功能上相似(产生相同的结果),请看不同的细节。你能详细说明一下,那个不正确的状态是什么吗?至于“显然是错误的”“,请参阅,第12.5章:*“以下数据类型的读写应为原子:(…)、
int
、(…)和引用类型。”。不,我很确定它们是原子的。当然不是,但没人这么说。读和写是原子的,但你所说的是两种不同的操作,这正是我在第一段中所写的。但是如果你看看OP的问题,你会发现它只不过是一个引用赋值,它是原子的,不需要同步。如果一个线程想将字符串字段设置为
Hi
,另一个线程想将字符串字段设置为
Hello
,那么在这个过程中没有任何东西会被“损坏”。此外,它与多核系统无关,单核系统使用多个线程没有问题,并且在没有同步的情况下也会出现相同的问题。您应该再次阅读OP的问题,并看到他的意图不是增加一个数字,而是“更新
string
值”。在它呈现的形式中,不,不需要任何类型的同步构造。
lock(_object)
{
   counter++;
}