为什么ReadWriteLockSlim这么慢?//这个自定义实现安全吗?
本文关键字:实现 安全 自定义 为什么 ReadWriteLockSlim | 更新日期: 2023-09-27 18:15:16
我编写了一个小型数据库,其中95%的使用率是读。我正在寻找瓶颈,出于好奇想比较可用锁定机制的速度:
在纯单线程环境中,我只得到读请求的结果:
no lock: 1%自旋锁:16%rwLock: 60%
我知道RWLock在多线程环境下看起来要好得多,但我不太明白为什么要花这么多时间才能获得一个读锁?
我写了一个小的自定义RW-lock,它的性能比rwLock好3倍,占总滴答数的20%。
代码如下:
class FastRWLock
{
private int _readers = 0;
private bool _isWriting = false;
private object _spinLock = new object();
private AutoResetEvent _notifier = new AutoResetEvent(false);
private bool needsNotify = false;
public void AquireReaderLock() {
if (_isWriting) {
lock (_spinLock) {
}
}
_readers++;
}
public void ExecuteWrite(Action a) {
if (_isWriting) {
lock (_spinLock) {//Only ends up here if another writer has already entered the following spinlock, thus, this one wont exite here until the previous write is done
}
}
try
{
_isWriting = true;
lock (_spinLock)//intention to write made public, idling until previous readers, that enqueued when another writeaction was active
{//probable deadlock?
if (_readers > 0) {
needsNotify = true;
_notifier.WaitOne();
needsNotify = false;
}
a.Invoke();
}
}
finally {
_isWriting = false;
}
}
public void ReleaseReaderLock() {
_readers--;
if (_readers < 1 && needsNotify) {
_notifier.Set();
}
}
}
这是一个可行的解决方案还是冒着死锁的风险?如果不是,那么标准RWLock还做了什么使它的性能如此差呢?
您需要使用易失性读写lock
块之外的变量,您可以读取缓存的值。
也不能在lock
块之外的多线程环境中执行_readers--
或_readers++
。你需要使用Interlocked.Increment
和Interlocked.Decrement
可能还有其他问题,但那些是我最先注意到的主要问题。
如果你修复了代码中的问题,我敢打赌你会看到更少的"性能增益",因为我认为性能增益是由代码中的错误引起的,这些错误使你的版本不可靠。正确地编写锁原语是非常困难的。我建议尽可能使用内置类。