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

时间:2016-10-26 14:17:35

标签: c# multithreading

我写了一个小数据库,其中使用率是95%。我一直在寻找瓶颈,出于好奇心想要比较可用锁定机制的速度:

在纯粹的单线程环境中,我只使用读取请求获得此结果:

无锁:1% 自旋锁:16% rwLock:60% 要完成的滴答声。

我知道RWLock在多线程环境中会看起来好多了,但是我不太清楚为什么只需要一个锁定阅读需要花费更多时间?

我写了一个小的自定义RW锁定,它比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还有什么能让它表现得更差?

1 个答案:

答案 0 :(得分:1)

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

此外,您无法在_readers--块之外的多线程环境中执行_readers++lock。您需要使用Interlocked.IncrementInterlocked.Decrement

可能还有其他问题,但是第一个跳到我身边的主要问题。

如果您修复了代码中的问题,我敢打赌您会看到更少的“性能提升”,因为我认为性能提升是由于代码中的错误导致您的版本不可靠使用。编写锁定原语很难正确完成。我建议尽可能使用内置类。