我使用ReaderWriterLockSlim已经有一段时间了,到目前为止,它已经满足了我的需求。随着我继续调优我的应用程序,我发现ReaderWriterLockSlim
对于我的用例来说是不太理想的。
根据文档(和我的经验),它偏爱作者而不是读者(即当读者和作者排队时,作者将获得优先)。然而,我需要一个对读者有利的等价物。我理解这些组件的副作用(特别是编写器饥饿问题)。
有没有人可以指出的可用于生产的等价物?谢谢。
发布于 2013-04-11 17:08:38
根据MSDN的说法,ReaderWriterLockSlim偏爱作者。这意味着当队列中有读取器和写入器时,写入器将获得优先级。
这会产生读者饥饿,测试代码重现这是here。我假设只有当写入是一个长操作,涉及到线程上下文切换时,才会发生饥饿。至少它总是在我的机器上重现,所以如果我错了,请告诉我。
另一方面,来自.net 2.0的ReaderWriterLock不会产生读取器和写入器匮乏,代价是性能降低。Here是从上一个示例中修改的代码,以显示没有发生饥饿。
所以,回到你的问题--这取决于你需要从RW lock获得什么功能。递归锁,异常处理,超时--最接近产品质量的RW锁,它支持以上所有功能,并支持读者可能是ReaderWriterLock。
你也可以采用维基文章中描述first readers-writers problem的代码,但当然你需要手动实现上面所需的所有功能,并且实现将会出现编写者匮乏的问题。
Lock core可能看起来像这样:
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个写入器线程,使用简单的内存操作(使用长阻塞操作将导致RWLockSlim的读取器匮乏和自定义锁的写入器匮乏):
我确保编译器不会展开工作负载循环,但可能还有其他我不知道的陷阱,因此请对这些测量持保留态度。测试的源代码是here。
https://stackoverflow.com/questions/14324748
复制相似问题