【问题标题】:Lock mechanism for Queue<T> during Enqueue and DequeueEnqueue 和 Dequeue 期间 Queue<T> 的锁定机制
【发布时间】:2010-12-03 22:05:46
【问题描述】:

在队列中,入队和出队都需要写锁。为什么有人会使用 ReaderWriterLockSlim 而不是只使用 lock{}?例如,

使用 ReaderWriterLockSlim

qLock.EnterWriteLock(); 
try 
{ 
    localQ.Enqueue(item); // or localQ.Dequeue(item)
} 

finally 
{ 
    qLock.ExitWriteLock(); 
} 

对战锁定{}

try 
{ 
    lock(qLock) { localQ.Enqueue(item);} // or localQ.Dequeue(item)
} 

【问题讨论】:

  • @Davita,在这种情况下,布赖恩的回答是错误的(但通常是正确的)。不幸的是,它有 3 个赞成票。
  • 感谢大家的回复。不幸的是,我想我还没有答案。我用 EnterReadLock() 得到 Peek() 部分,但如果我的逻辑只是 Enqueue() 和 Dequeue() 我需要 EnterWriterLock() 无论如何。如果我处于锁定状态{}并说它的获取被无限期延迟或说很长; lock 不提供容错,并且有可能陷入死锁或阻塞情况。 ReaderWriterLock 或 ReaderWriterLockSlim 不会为我提供容错选项来避免死锁或长时间阻塞。想法?还是我不在这儿了

标签: c# multithreading thread-safety


【解决方案1】:

ReaderWriterLockSlim 的使用主要是在有很多线程经常从资源读取但只有少数线程写入资源的情况下的性能优化。

Monitor 类(由 lock 语句使用)获取资源的排他锁 - 这意味着读取器和写入器都被阻塞。然而,在许多情况下,阅读比写作频繁得多。在这些情况下,使用读/写锁允许多个读者同时进入锁,但一次只能有一个写者(当所有排队的读者都出局时)。

在您的示例中,读取器/写入器锁仅在有其他代码在队列中窥视而不使项目出队时才有意义 ...否则所有操作都是变异写入,并且@987654322 @ 语句会更合适。

【讨论】:

    【解决方案2】:

    好吧,这仍然允许读者Peek,而不需要写lock。不过,很难想象这在实际应用中会有什么用处。

    【讨论】:

      【解决方案3】:

      在这种情况下,ReaderWriterLockSlim 并没有提供任何真正的优势。没错,EnqueueDequeue 都是写操作,需要独占写锁。

      对于确实具有读取操作的集合,就像大多数集合一样,那么ReaderWriterLockSlim 会比总是使用lock 更好。

      我能想到的唯一小优势是一致性。如果在大多数地方使用ReaderWriterLockSlim,因为大多数其他集合用于大量读取和少量写入,那么开发和维护在任何地方都使用ReaderWriterLockSlim会更容易。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多