为什么ReaderWriterLockSlim在EnterReadLock()内调用Sleep()?

时间:2019-04-08 14:53:15

标签: c# .net multithreading locking readerwriterlockslim

我正在尝试实现一个线程安全的资源池,该资源池可以快速访问并且仅偶尔获得更新。为此,我使用带有扩展方法的ReaderWriterLockSlim来输入和退出读取锁。分析线程利用率时出人意料地非常低。

我确认没有对池进行任何写操作,因此从未调用EnterWriteLock()。

internal Mesh GetMesh(string name)
{
    using (CacheLock.Read())
    {
        if (MeshDictionary.TryGetValue(name, out var m))
        {
            return m;
        }
    }
    // <snip>
}
public static ReadLock Read(this ReaderWriterLockSlim l)
{
    return new ReadLock(l);
}
internal class ReadLock : IDisposable
{
    private readonly ReaderWriterLockSlim _lockObject;
    public ReadLock(ReaderWriterLockSlim l)
    {
        _lockObject = l;
        l.EnterReadLock();
    }
    public void Dispose()
    {
        _lockObject.ExitReadLock();
    }
}

在进行概要分析时,我发现大多数线程在EnterReadLock()中花费大约25%的时间。该功能的内部睡眠大约需要19%,其余时间是用于主动旋转的时间和其他开销。 我希望EnterReadLock根本不会睡觉,而只会旋转一小段时间。 有没有一种方法可以提高利用率并减少等待时间?

1 个答案:

答案 0 :(得分:1)

线程组件的Slim版本使用自旋锁,这是快速的,但会占用大量CPU。如果您希望等待任何时间,请使用较旧的ReaderWriterLock。