为什么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还做了什么使它的性能如此差呢?

为什么ReadWriteLockSlim这么慢?//这个自定义实现安全吗?

您需要使用易失性读写lock块之外的变量,您可以读取缓存的值。

也不能在lock块之外的多线程环境中执行_readers--_readers++。你需要使用Interlocked.IncrementInterlocked.Decrement

可能还有其他问题,但那些是我最先注意到的主要问题。

如果你修复了代码中的问题,我敢打赌你会看到更少的"性能增益",因为我认为性能增益是由代码中的错误引起的,这些错误使你的版本不可靠。正确地编写锁原语是非常困难的。我建议尽可能使用内置类。