是否有一个ReaderWriterLockSlim等同于读者?

Igo*_*huk 16 .net c# concurrency multithreading readerwriterlockslim

我已经使用了ReaderWriterLockSlim一段时间了,到目前为止它已经满足了我的需求.当我继续微调我的应用程序时,我发现这ReaderWriterLockSlim对我的用例来说有点不理想.

根据文献(和我的经验),它有利于作家而不是读者(即当读者和作家排队时,作家会得到偏好).但是,我需要一个有利于读者的同等学历.我理解这种成分的副作用(特别是作家饥饿问题).

是否有人可以指出的任何生产就绪的等价物?谢谢.

Ale*_*der 7

根据MSDN,ReaderWriterLockSlim偏爱作家.这意味着当队列中有读者和作者时,作者会得到偏好.

这可以产生读者饥饿,重现的测试代码就在这里.我假设只有在写入是一个涉及线程上下文切换的长操作时才会发生饥饿.至少它总是在我的机器上复制,所以请告诉我,如果我错了.

另一方面,来自.net 2.0的ReaderWriterLock不会以降低性能为代价产生读者和作者的饥饿.以下是上一个示例中的修改代码,以显示没有发生饥饿.

所以,回到你的问题 - 这取决于你需要RW Lock的功能.递归锁定,异常处理,超时 - 与生产质量最接近的RW锁定支持以上所有,并且有利于读者可能是ReaderWriterLock.

你也可以采用维基文章中描述第一个读者 - 作者问题的代码,当然你需要手动实现上面所有必需的功能,实现会有编写者饥饿问题.

锁核心可能看起来像这样:

class AutoDispose : IDisposable 
{ 
  Action _action; 
  public AutoDispose(Action action) 
  { 
    _action = action; 
  }
  public void Dispose()
  {
    _action();
  }
}

class Lock
{
  SemaphoreSlim wrt = new SemaphoreSlim(1);
  int readcount=0;

  public IDisposable WriteLock()
  {
    wrt.Wait();
    return new AutoDispose(() => wrt.Release());
  }

  public IDisposable ReadLock()
  {
    if (Interlocked.Increment(ref readcount) == 1)
        wrt.Wait();

    return new AutoDispose(() => 
    {
      if (Interlocked.Decrement(ref readcount) == 0)
         wrt.Release();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

比较3个实现的性能,使用3个读取器和3个写入器线程,使用简单的内存操作(使用长阻塞操作会产生RWLockSlim的读取器饥饿和自定义锁定的编写器饥饿):

性能比较

我确保工作负载循环不是由编译器展开的,但是可能还有其他我不知道的缺陷,所以请将这些测量结果与之相提并论.测试的源代码在这里.