C# Interlocked functions as a lock mechanism?

走远了吗. 提交于 2020-01-02 09:56:02

问题


While I was reading about ReaderWriterLockSlim lock mechanism , There was this guy who suggested that Interlock Functions can be used for a finer locking

Also, I found here another answer from Marc :

...Writes make their change to a cloned copy, then use Interlocked.CompareExchange to swap the reference (re-applying their change if another thread mutated the reference in the interim).

Well , Currently all I know about Interlocked object , is that it is used (in a multithreaded environment) to do atomic additions, compare , compareExchange operations. (and I know how to use it)

But (and here is my question) —

Question

How can I use it as a lock ? ( sample code will be much appreciated)

edit

For simplicity , I'm pasting this code ( which is not thread safe - if Go was called by two threads simultaneously, it would be possible to get a division-by-zero error) :

class ThreadUnsafe
 {
   static int _val1 = 1, _val2 = 1;

   static void Go()
       {
        if (_val2 != 0) Console.WriteLine (_val1 / _val2);
        _val2 = 0;
       }
}

How can I use Interlock to replace the lock (which would have solved the problem) ?


回答1:


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.




回答2:


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;
}


来源:https://stackoverflow.com/questions/23842935/c-sharp-interlocked-functions-as-a-lock-mechanism

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