C# Interlocked functions as a lock mechanism?

Deadly 提交于 2019-12-06 05:09:47

Interlocked is used to implement lockless algorithms and data structures. It's therefore not "finer locking", or even locking at all. It lets you do small and well-defined operations safely in a multi-threaded environment: for instance, if you want two threads to increment the same variable, you can use Interlocked to do it instead of acquiring a heavyweight lock and using the "regular increment".

However, there are many, many things that you can't do with Interlocked that you could do under a regular lock. For instance, anything that involves modifying more than one variable atomically generally can't be done with Interlocked, so you wouldn't be able to use it for your example.

Interlocked can, however, help developers implement locking mechanism, though you might as well use the built-in ones. Most locks require kernel support to interrupt the blocked thread until the lock becomes available. Therefore, the only kind of lock that you can implement with Interlocked alone is a spin lock: a lock that threads continually try to acquire until it works.

class InterlockedLock
{
    private int locked;

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

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

In this example, locked is initially zero. When a thread tries to acquire it for the first time, locked becomes 1, and subsequent threads trying to Lock it will spin until someone calls Unlock to make locked 0 again.

Locking with Interlocked is done by replacing a new value with an old value only if the old value hasn't changed. If it has we try again until it doesn't (spinning).

This can be used to replace fine grained locks that only update a single value or to implement a lightweight locking mechanism like SpinLock.

Example:

private int _value;

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

Instead of:

lock(_lock)
{
    _value = newValue;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!