gpt4 book ai didi

c# - Interlocked.CompareExchange 真的比简单的锁更快吗?

转载 作者:太空狗 更新时间:2023-10-29 20:49:13 26 4
gpt4 key购买 nike

我遇到了 .NET 3.5 的 ConcurrentDictionary 实现(很抱歉我现在可以找到链接),它使用这种锁定方法:

var current = Thread.CurrentThread.ManagedThreadId;
while (Interlocked.CompareExchange(ref owner, current, 0) != current) { }

// PROCESS SOMETHING HERE

if (current != Interlocked.Exchange(ref owner, 0))
throw new UnauthorizedAccessException("Thread had access to cache even though it shouldn't have.");

代替传统的lock:

lock(lockObject)
{
// PROCESS SOMETHING HERE
}

问题是:这样做有什么真正的理由吗?它是更快还是有一些隐藏的好处?

PS:我知道在某些最新版本的 .NET 中有一个 ConcurrentDictionary,但我不能将其用于遗留项目。

编辑:

在我的特定情况下,我所做的只是以线程安全的方式操作内部 Dictionary 类。

例子:

public bool RemoveItem(TKey key)
{
// open lock
var current = Thread.CurrentThread.ManagedThreadId;
while (Interlocked.CompareExchange(ref owner, current, 0) != current) { }


// real processing starts here (entries is a regular `Dictionary` class.
var found = entries.Remove(key);


// verify lock
if (current != Interlocked.Exchange(ref owner, 0))
throw new UnauthorizedAccessException("Thread had access to cache even though it shouldn't have.");
return found;
}

正如@doctorlove 所建议的,这是代码:https://github.com/miensol/SimpleConfigSections/blob/master/SimpleConfigSections/Cache.cs

最佳答案

您的问题没有明确的答案。我会回答:视情况而定

您提供的代码的作用是:

  1. 等待对象处于已知状态(threadId == 0 == no current work)
  2. 工作
  3. 将已知状态设置回对象
  4. 现在另一个线程也可以工作了,因为它可以从第 1 步转到第 2 步

正如您所注意到的,代码中有一个循环实际执行“等待”步骤。 您不会阻塞线程,直到您可以访问您的关键部分,您只是消耗 CPU 而不是。尝试用 Thread.Sleep(2000) 替换您的处理(在您的情况下,调用 Remove),您会看到另一个“等待”线程消耗了所有你的一个 CPU 循环 2s。

也就是说,哪个更好取决于几个因素。例如:有多少个并发访问?手术需要多长时间才能完成?你有多少个 CPU?

我会使用 lock 而不是 Interlocked 因为它更容易阅读和维护。异常(exception)情况是您有一段代码被调用了数百万次,并且您确定 Interlocked 更快的特定用例。

因此您必须自己衡量这两种方法。如果您没有时间这样做,那么您可能不需要担心性能问题,您应该使用 lock

关于c# - Interlocked.CompareExchange 真的比简单的锁更快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20800954/

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