多级锁?

时间:2018-11-16 13:18:42

标签: c# multithreading parallel-processing locking

在并行处理方面,我有一个Parallel.For循环,它对可枚举进行查找,如果找不到要添加的内容,则将其添加。我一直遇到一个问题,其中一个线程修改了可枚举,而另一个线程进行查找,这使它抛出异常。显而易见的解决方案是在查询和条目上都使用lock,但这有点蛮力。我希望它能够运行多个并发查找,所以我不想在一个线程进行查找时完全锁定它,但是我想禁止它在查找过程中进行添加。有什么办法可以像这样进行两级锁定吗?

2 个答案:

答案 0 :(得分:4)

您可能想使用ReaderWriterLock

private ReaderWriterLockSlim lock = new ReaderWriterLockSlim();

public string Read () {
    lock.EnterReadLock ();
    try {
        return "xxx";
    } finally {
        lock.ExitReadLock();
    }
}

public void Write () {
    lock.EnterWriteLock ();
    try {
        // ...
    } finally {
        lock.ExiteWriteLock ();
    }
}

多个线程可能拥有ReaderWriterLock的“读者”部分,但只有一个人可以拥有“作家”部分(并且有作家的情况下就没有读者)。

答案 1 :(得分:0)

我会考虑使用某种形式的不可变集合和Interlocked来替换共享实例。

例如您提到“查找”,那么ImmutableDictionary会是一个很好的匹配吗?

然后进行查找和更新,您将得到以下内容:

var local = sharedReference;
while(!local.ContainsKey(lookupValue))
{
    var newValue = /* Whatever */
    var newLocal = local.Add(lookupValue,newValue);
    var result = Interlocked.CompareExchange(ref sharedReference, newLocal, local);
    if(result == local) break;
    local = result;
}
//At this point, local definitely contains a key for lookupValue