【问题标题】:ReaderWriterLock vs lock{}ReaderWriterLock 与锁{}
【发布时间】:2010-01-22 11:49:00
【问题描述】:

请说明主要区别是什么,我应该什么时候使用。
专注于 Web 多线程应用程序。

【问题讨论】:

    标签: c# .net multithreading


    【解决方案1】:

    lock 只允许一个线程同时执行代码。 ReaderWriterLock 可能允许多个线程同时读取或对写入具有独占访问权限,因此它可能更有效。如果您使用的是 .NET 3.5,ReaderWriterLockSlim 会更快。因此,如果您的共享资源的读取频率高于写入频率,请使用ReaderWriterLockSlim。使用它的一个很好的例子是您经常阅读的文件(在每个请求上)并且您很少更新文件的内容。因此,当您从文件中读取时,您输入一个读锁,以便许多请求可以打开它进行读取,当您决定写入时,您输入一个写锁。在文件上使用lock 基本上意味着您一次可以处理一个请求。

    【讨论】:

    • 那么你的意思是,如果第一个线程读取的值在 lock{} 内,没有其他线程可以同时读取它?
    • 没错,lock 将只允许一个线程执行锁语句的主体。
    • “所以它可能更有效”:但可能不会,你的代码会更复杂。它应该保留给小众案例。
    • BTW ReaderWriterLock 已弃用,取而代之的是 ReaderWriterLockSlim。如果您选择使用其中一种,请使用后一种。
    • @flq:如果您在没有先授予读锁的情况下允许读取(并确保在完成后释放您的读锁),那么您可能不知道何时发出写锁是安全的因为您不会跟踪相关代码块的读取使用者。
    【解决方案2】:

    如果您有很多线程只需要读取数据并且这些线程被阻塞等待锁定并且您不经常这样做,请考虑使用 ReaderWriterLock需要更改数据。

    但是 ReaderWriterLock 可能会阻塞等待写入很长时间的线程。

    因此,只有在您确认您在“现实生活”中获得 高度竞争的锁并且您确认可以使用后才使用 ReaderWriterLock不要重新设计您的锁定设计以减少锁定的时间

    还要考虑您是否不能将共享数据存储在数据库中并让它处理所有锁定,因为如果数据库速度很快,这不太可能让您难以追踪错误足以满足您的应用需求。

    某些情况下,您还可以使用 Aps.net 缓存来处理共享数据,并在数据更改时从缓存中删除该项目。下一次读取可以将新副本放入缓存中。

    记住

    “最好的锁定是 锁定你不需要(即不要 在线程之间共享数据)。”

    【讨论】:

      【解决方案3】:

      监视器和可与任何引用对象关联的底层“同步块”(C# 的lock 下的底层机制)支持独占执行。只有一个线程可以拥有锁。这既简单又高效。

      ReaderWriterLock(或者,在 V3.5 中,ReaderWriterLockSlim 更好)提供了一个更复杂的模型。 除非你知道,否则避免这样会更有效率(即有性能测量来支持你自己)。

      最好的锁定是您不需要的锁定(即不要在线程之间共享数据)。

      【讨论】:

      • +1 表示“最好的锁定是您不需要的锁定(即不要在线程之间共享数据)。”
      【解决方案4】:

      ReaderWriterLock 允许您让多个线程同时持有 ReadLock... 这样您的共享数据可以同时被多个线程使用。一旦请求了 WriteLock,就不再授予 ReadLocks,等待 WriteLock 的代码被阻塞,直到所有具有 ReadLocks 的线程都释放它们。

      WriteLock 只能由一个线程持有,让您的“数据更新”从代码消耗部分的角度来看是原子的。

      另一方面,锁只允许一个线程一次进入,不允许线程只是尝试使用共享数据。

      ReaderWriterLockSlim 是 ReaderWriterLock 的一个性能更高的新版本,它更好地支持递归,并且能够让线程从本质上是 ReadLock 的 Lock 平滑地移动到 WriteLock (UpgradeableReadLock)。

      【讨论】:

        【解决方案5】:

        ReaderWriterLock/Slim 专为帮助您有效锁定多消费者/单生产者场景而设计。使用 lock 语句这样做是可能的,但效率不高。 RWL/S 通过主动自旋锁来获取锁而占据上风。这也可以帮助您避免锁护送,这是 lock 语句的问题,即线程在无法获取锁时放弃其线程量子,使其落后,因为它不会被重新调度一段时间。

        【讨论】:

          【解决方案6】:

          ReaderWriterLockSlim 确实比 ReaderWriterLock 快。但是 ReaderWriterLockSlim 的内存消耗是非常惊人的。尝试附加内存分析器并亲自查看。我会随时选择 ReaderWriterLock 而不是 ReaderWriterLockSlim。

          【讨论】:

          • 有多离谱?你能在你的陈述中添加数字吗?
          【解决方案7】:

          我建议查看http://www.albahari.com/threading/part4.aspx#_Reader_Writer_Locks。它谈到了 ReaderWriterLockSlim(你想用它来代替 ReaderWriterLock)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-26
            • 1970-01-01
            相关资源
            最近更新 更多