gpt4 book ai didi

c# - 如何在 C# 中实现我自己的 TaS-Lock?

转载 作者:太空狗 更新时间:2023-10-29 23:12:56 26 4
gpt4 key购买 nike

因此,对于一项任务,我们需要选择使用 C#-Lock 或使用自行实现的 TaS-Lock。我读到的有关 TaS-Locks 的内容是,它使用 1 个原子步骤来读取和写入值。有人建议我们为此使用 C# 中的 Interlocked 类。

到目前为止,这就是我所得到的,但它似乎导致了不一致的答案:

public interface Lock
{
void Lock();
void Unlock();
}

public class C_Sharp_Lock : Lock
{
readonly Object myLock = new object();

public void Lock()
{
Monitor.Enter(myLock);
}

public void Unlock()
{
Monitor.Exit(myLock);
}
}

public class Tas_Lock : Lock
{
int L = 0;

public void Lock()
{
while (0 == Interlocked.Exchange(ref L, 1)) { };
}

public void Unlock()
{
Interlocked.Exchange(ref L, 0);
}
}

有谁知道我在这里做错了什么?

编辑:作为对凯文的回应:

我已将其更改为以下内容:

public class Tas_Lock : Lock
{
int L = 0;

public void Lock()
{
while (0 == Interlocked.CompareExchange(ref L, 1, 0)) { };
}

public void Unlock()
{
Interlocked.Exchange(ref L, 0);
}
}

然而,这仍然会返回不一致的结果。

编辑 #2: 对 C# 锁的更改:

public class C_Sharp_Lock : Lock
{
readonly Object myLock = new object();
bool lockTaken = false;

public void Lock()
{
Monitor.Enter(myLock, ref lockTaken);
}

public void Unlock()
{
if (lockTaken)
Monitor.Exit(myLock);
}
}

最佳答案

您误解了 Interlocked.CompareExchange 的工作方式。如果它之前等于提供的比较对象,它会自动交换一个值,并返回之前的值

简而言之,Interlocked.CompareExchange(ref L, 1, 0) 将:

  • 检查L是否等于0
  • 如果L等于0,那么它会将L设置为1并返回之前的值(0)
  • 如果 L 不等于 0(因此等于 1),则它将返回先前的值 (1)

从那里开始,您应该做的是循环 until Interlocked.CompareExchange 返回 0(这意味着已获取锁)。在您的代码中,您正在等待 Interlocked.CompareExchange 返回 0。

固定代码:

public class Tas_Lock
{
int L = 0;

public void Lock()
{
while (0 != Interlocked.CompareExchange(ref L, 1, 0)) { }
}

public void Unlock()
{
Interlocked.Exchange(ref L, 0);
}
}

需要注意两点:

  • Unlock 中的 Interlocked.Exchange 可以替换为更快的 Volatile.Write(或者甚至是简单的写入,尽管有争议)
  • 如果不是为了分配,您可以使用内置类 SpinLock,它已经以优化的方式完成了所有这些工作

关于c# - 如何在 C# 中实现我自己的 TaS-Lock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40871859/

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