Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有一个ReaderWriterLockSlim的等价物对读者有利?_C#_.net_Multithreading_Concurrency_Readerwriterlockslim - Fatal编程技术网

C# 是否有一个ReaderWriterLockSlim的等价物对读者有利?

C# 是否有一个ReaderWriterLockSlim的等价物对读者有利?,c#,.net,multithreading,concurrency,readerwriterlockslim,C#,.net,Multithreading,Concurrency,Readerwriterlockslim,我已经使用了一段时间,到目前为止,它满足了我的需求。当我继续微调我的应用程序时,我发现对于我的用例来说,readerwriterlocksim稍微不太理想 根据文档(以及我的经验),它更青睐作者而不是读者(即,当读者和作者排队时,作者将获得优先权)。然而,我需要一个有利于读者的等价物。我理解这种成分的副作用(特别是作家饥饿问题) 有人可以指出生产准备就绪的等价物吗?谢谢。根据MSDN,ReaderWriterLockSlim偏爱作家。这意味着当队列中有读卡器和写卡器时,写卡器将获得优先权 这会产

我已经使用了一段时间,到目前为止,它满足了我的需求。当我继续微调我的应用程序时,我发现对于我的用例来说,
readerwriterlocksim
稍微不太理想

根据文档(以及我的经验),它更青睐作者而不是读者(即,当读者和作者排队时,作者将获得优先权)。然而,我需要一个有利于读者的等价物。我理解这种成分的副作用(特别是作家饥饿问题)


有人可以指出生产准备就绪的等价物吗?谢谢。

根据MSDN,ReaderWriterLockSlim偏爱作家。这意味着当队列中有读卡器和写卡器时,写卡器将获得优先权

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

另一方面,来自.NET2.0的ReaderWriterLock不会产生读写器饥饿,但会降低性能。修改了前一个示例中的代码,以显示没有发生饥饿

所以,回到你的问题——这取决于你需要RW锁的哪些特性。 递归锁、异常处理、超时-最接近生产质量的RW锁,它支持上述所有功能,并支持读卡器可能是ReaderWriterLock

您也可以采用wiki文章中描述的代码,但当然您需要手动实现上面的所有必需功能,并且实现将有编写器饥饿问题

锁芯可能如下所示:

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();
    });
  }
}
比较3种实现的性能,使用3个读卡器线程和3个写卡器线程,使用简单的内存内操作(使用长阻塞操作将导致rwlocksim的读卡器饥饿和自定义锁的写卡器饥饿):


我确保编译器不会展开工作负载循环,但可能还有其他我不知道的陷阱,所以对这些度量采取谨慎态度。测试的源代码是。

没有代码永远无法得到确凿的证明。但是不,那是不太可能的。请避免问购物问题。如果你喜欢阅读,为什么不用更新的克隆来替换内部列表呢?您的代码将是无锁的,但更新时会有一些负担。是的,听起来您可以像jgauffin建议的那样使用一个副本来解决这个问题,或者如果数据结构对于便宜的副本来说太大,那么可以使用写缓冲区来减少写操作的频率。然后,您可以通过上下调整缓冲区刷新时间来调整读/写平衡。请问您在保护什么?我最近删除了ReaderWriterLockSlim的所有用法,效果非常好。回答非常详细!非常感谢,我来看看。