Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.3k views
in Technique[技术] by (71.8m points)

c# - Do embedded locks add any value against race conditions?

I've been facing a few race conditions in my code lately and I'm wondering if secondary/tertiary locks actually add any value. They seem very redundant, and this SO post seems to align with my thought process on it by stating:

In order to prevent race conditions from occurring, you would typically put a lock around the shared data to ensure only one thread can access the data at a time. This would mean something like this:

obtain lock for x ... release lock for x

Given this simple example to remove empty queues from a collection:

Dictionary<Guid, Queue<int>> _queues = new Dictionary<Guid, Queue<int>>();

...

lock (_queues) {
    while (_queues.Any(a => a.Value.Count == 0)) {
        Guid id = _queues.First(f => f.Value.Count == 0);
        if (_queues.ContainsKey(id))
            lock (_queues)
                _queues.Remove(id);
    }
}

Does the second lock provide any value?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In the code that you posted, no, the second lock does not add any value, as it is not possible to get to that code without executing the while loop first, at which point the mutex will already have been locked.

It is probably important to note that it doesn't hurt to have it in there, though, as C# locks are reentrant.

Where the second lock does add value is in code where it is not clear that the first lock will always be obtained. For example:

void DoWork1()
{
    lock(_queues)
    {
        //do stuff...
        if(condition)
            DoWork2();
    }
}

void DoWork2()
{
    lock(_queues)
    {
        //do stuff...
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...