gpt4 book ai didi

c# - 对 Interlocked.Increment 和 Lock 的使用感到困惑

转载 作者:行者123 更新时间:2023-11-30 19:11:15 24 4
gpt4 key购买 nike

我了解 Interlocked.Incrementlock() 的功能。但是我对何时使用其中一个感到困惑。据我所知,Interlocked.Increment 会增加共享的 int/long 值,而 lock() 是用来锁定代码区域的。

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

lock(_object)
{
sharedString = "Hi";
}

但是,这对于 Interlocked 类是不可能的。

  • 为什么这不能通过 Interlocked 完成?
  • 这些同步机制有什么区别?

最佳答案

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

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

此外,使用 lock() 会发出内存屏障,确保从多个 CPU 访问相同的变量会产生同步(非陈旧)数据。这在其他语言/平台中并非如此,必须显式执行内存屏障和防护。

对整数值使用 Interlocked 方法会更有效,因为硬件本身就支持执行必要的同步。但是此硬件支持仅存在于 __int32 和 __int64 等 native 积分中,因为硬件没有更高级别复杂类型的概念,因此 Interlocked 类型没有公开此类高级方法。因此,您不能使用 Interlocked 来同步 System.String 或任何 System.Object 派生类型的分配。

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

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

关于c# - 对 Interlocked.Increment 和 Lock 的使用感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12315109/

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