C#联锁功能作为锁定机构?

C#联锁功能作为锁定机构?,c#,multithreading,locking,interlocked,C#,Multithreading,Locking,Interlocked,当我阅读有关readerwriterlocksimlock机制的文章时,谁建议Interlock函数可以用于更精细的锁定 另外,我从Marc那里找到了另一个答案: …写入操作将其更改为克隆副本,然后使用 Interlocated.CompareExchange交换引用(重新应用 如果另一个线程在此期间改变了引用,则进行更改) 嗯,目前我所知道的关于联锁对象的所有信息是,它(在多线程环境中)用于执行原子的添加,比较,比较交换操作。(我知道如何使用它) 但是(这是我的问题)- 问题 我怎么能把它当锁

当我阅读有关
readerwriterlocksim
lock机制的文章时,谁建议
Interlock
函数可以用于更精细的锁定

另外,我从Marc那里找到了另一个答案:

…写入操作将其更改为克隆副本,然后使用 Interlocated.CompareExchange交换引用(重新应用 如果另一个线程在此期间改变了引用,则进行更改)

嗯,目前我所知道的关于
联锁
对象的所有信息是,它(在多线程环境中)用于执行原子的
添加
比较
比较交换
操作。(我知道如何使用它)

但是(这是我的问题)-

问题

我怎么能把它当锁用呢?(示例代码将不胜感激)

编辑 为了简单起见,我粘贴了这段代码(这不是线程安全的-如果两个线程同时调用了
Go
,那么就有可能得到零除错误):


如何使用Interlock替换锁(这会解决问题)?

使用
Interlocked
进行锁定是通过仅在旧值未更改的情况下将新值替换为旧值来完成的。如果有,我们再试一次,直到它没有(旋转)

这可以用来替换只更新单个值的细粒度锁,或者实现轻量级锁机制,如

示例

private int _value;

int oldValue;
int originalValue;
do
{
    oldValue = _value;
    originalValue = Interlocked.CompareExchange(ref _value, newValue, oldValue);
}
while (originalValue != oldValue);
lock(_lock)
{
    _value = newValue;
}
而不是

private int _value;

int oldValue;
int originalValue;
do
{
    oldValue = _value;
    originalValue = Interlocked.CompareExchange(ref _value, newValue, oldValue);
}
while (originalValue != oldValue);
lock(_lock)
{
    _value = newValue;
}

联锁
用于实现无锁算法和数据结构。因此,它不是“更精细的锁定”,甚至根本不是锁定。它允许您在多线程环境中安全地执行小型和定义良好的操作:例如,如果您希望两个线程递增相同的变量,您可以使用
Interlocked
来执行此操作,而不是获取重量级锁并使用“常规递增”

然而,有很多事情是你不能用
联锁的
做的,你可以在常规锁下做。例如,任何涉及原子地修改多个变量的操作通常都不能通过
Interlocked
完成,因此您无法将其用于示例

Interlocked
可以帮助开发人员实现锁定机制,不过您也可以使用内置机制。大多数锁需要内核支持来中断被阻止的线程,直到锁可用为止。因此,您可以单独使用
Interlocked
实现的唯一一种锁是旋转锁:线程不断尝试获取的锁,直到它工作为止

class InterlockedLock
{
    private int locked;

    public void Lock()
    {
        while (Interlocked.CompareExchange(ref locked, 1, 0) != 0)
            continue; // spin
    }

    public void Unlock()
    {
        locked = 0;
    }
}

在本例中,
locked
最初为零。当一个线程第一次尝试获取它时,
locked
变为1,随后尝试
Lock
的线程将旋转,直到有人调用
Unlock
再次使
锁定
0。

我如何将其用作锁?-通过使用
lock(){}
。您希望
volatile
确保对
locked
的写入不会被进一步重新排序,从而在关键部分中的任何写入之前结束。