C#线程性能,99%的时间都是一个线程

时间:2009-08-06 20:24:06

标签: c# multithreading

我有一个多线程C#应用程序。有一个字典可以同时从N个不同的线程访问。 99%的呼叫来自线程A,其余的来自B,C,......

现在,我只是在每次访问时锁定字典。但这看起来很浪费,因为99%的时间我都在调用锁,线程A已经锁定了。

这样做更有效的方法是什么?

线程B,C,......可能需要某种类型的.Begin和.End调用,然后线程A只需在每次调用时检查一位,看看是否有其他线程正在使用字典。有没有人有这样的代码样本以线程安全的方式实现?

5 个答案:

答案 0 :(得分:4)

您需要仔细检查您的探查器数据。

除非存在实际争用,否则Monitor和RWLSlim实际上都不会“硬锁”(如下拉到OS原语);在所有其他情况下,它将使用Interlocked,并且其影响相对最小(除了缓存刷新)。

性能方面,RWLockSlim的创建成本相对较高,而且比Monitor要贵一点。它的优点是允许多个读者和一个作家。

如果您看到硬锁出现,那么您有实际的争用,在这种情况下,您所说的99%/ 1%/ 1%/ 1%/ ...比率可能并不反映现实。

正如之前的海报所指出的那样,你应该使用它 - 在大多数情况下你会偶尔写入和大量读取,否则系统的一致性有点难以实施。如果是这种情况,RWlockSlim应该删除不必要的争用。

底线:这一切都取决于你想要做什么 - 就像这本词典的用途和访问方式一样。有时候扩大锁定以防止占用过多的锁定是有意义的,在某些情况下 - 非常罕见 - 你甚至可能想要使用像Interlocked这样的无锁式原语,甚至在尝试点击“真正的”锁定之前。

也许如果你告诉我们更多关于这个场景的信息,我们可以提供更好的帮助。

答案 1 :(得分:2)

如何执行锁定。对于阅读,您不需要以同样的“硬”方式锁定其他线程,就像您还要更新一样。无论哪种方式,您都可以在读取操作中更松散。我建议调查ReaderWriterLockSlim(除非你已经在使用它):

class DictionaryHolder
{
    private IDictionary<int, string> _data = new Dictionary<int, string>();
    private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
    public void Update(int key, string value)
    {
        _lock.EnterWriteLock();            
        try
        {
            _data[key] = value;
        }
        finally
        {
            _lock.ExitWriteLock();
        }
    }

    public string GetValue(int key)
    {
        _lock.EnterReadLock();
        try
        {
            if (_data.ContainsKey(key))
            {
                return _data[key];
        }
        finally
        {
            _lock.ExitReadLock();
        }
    }
}

这将允许多个线程“同时”从字典中读取,同时在更新时阻止来自其他线程的访问。

答案 2 :(得分:2)

除非探查器告诉您在Monitor.Enter和公司中花费了大量时间,否则您不应该担心这一点 - 通常,获取无人控制的锁或您已经拥有的锁是一个非常快速的操作,应该是性能与您建议的位检查相似。锁定操作通常只有在由于争用而必须阻塞时才会很慢。

答案 3 :(得分:1)

当有许多读者和少数作家时,ReaderWriterLockSlim会提供帮助。但是,根据以下链接,ReaderWriterLockSlim的个别操作性能似乎比Monitor更差:A Performance Comparison of ReaderWriterLockSlim with ReaderWriterLock

您可以尝试的一个选项是使用Interlocked操作和Event对象来同步线程。但是,您应该再次测量这种方法的性能。

答案 4 :(得分:0)

尝试在.NET 4.0中使用System.Collections.Concurrent.ConcurrentDictionary

它的设计是线程安全的