【问题标题】:Mutex lock on write only只写互斥锁
【发布时间】:2010-12-08 18:51:57
【问题描述】:

我有一个多线程 C++ 应用程序,它在内存中保存一个复杂的数据结构(缓存数据)。

当我刚刚读取数据时,一切都很好。我可以拥有任意数量的线程来访问数据。

但是缓存的结构不是静态的。

  • 如果请求的数据项不可用,它将从数据库中读取,然后插入到数据树中。这可能也没有问题,即使我在将新数据项添加到树中时使用互斥锁,也只需要几个周期(它只是添加一个指针)。
  • 有一个不时执行的垃圾收集进程。它从树中删除所有旧项目。为此,我需要锁定整个事情,以确保当前没有其他进程正在访问任何将从内存中删除的数据。当我从缓存中读取数据时,我还必须锁定树,这样我就不会在处理项目时删除它们(有点“反之亦然”)。

“伪代码”:

function getItem(key)
   lockMutex()
   foundItem = walkTreeToFindItem(key)
   copyItem(foundItem, safeCopy)
   unlockMutex()
   return safeCopy
end function

function garbageCollection()
   while item = nextItemInTree
      if (tooOld) then
         lockMutex()
         deleteItem(item)
         unlockMutex()
      end if
   end while
end function

困扰我的是:这意味着我必须在阅读时锁定树(以避免在阅读时开始垃圾收集)。但是 - 作为副作用 - 我也不能同时进行两个阅读过程。

有什么建议吗?

是否有某种“这是一个只读操作,只与写入冲突”互斥锁?

【问题讨论】:

标签: c++ linux multithreading mutex


【解决方案1】:

查看read-write-lock

您没有指定可以使用哪个框架,但pThreadboost 都实现了该模式。

【讨论】:

    【解决方案2】:

    正如其他人所说,这个概念是一个“共享阅读器,单一作者”锁。在 Linux 环境中,您应该能够在没有任何框架的情况下使用 pthread_rwlock_t。我建议也调查一下boost::shared_lock

    【讨论】:

      【解决方案3】:

      我建议reader-writer lock。这个想法是你可以获得一个“读”或“写”的锁,锁将允许多个读者,但只允许一个写者。非常方便。

      【讨论】:

      • 还有一个排队的原则,这样如果一个写者请求访问,它就不必等待一段时间的非读,而是延迟未来的读请求,直到它获得它的访问并执行其工作。
      【解决方案4】:

      在 C++17 中,std::shared_mutex 直接支持这种类型的访问(多读、单写)。我认为这是从 boost::shared_lock 采用的。该主题还在 Anthony Williams 的 C++ Concurrency in Action 中通过示例进行了描述。 https://livebook.manning.com/book/c-plus-plus-concurrency-in-action-second-edition/chapter-3/185.

      基本位是:

      • 在允许共享访问的读取上使用 std::shared_lock
        • 现有的 shared_lock 不会阻止新的 shared_lock 锁定
      • 在需要独占访问的更新/写入函数上使用 std::unique_lock
        • 将等待所有现有共享读取以及其他写入完成
        • 在锁定时排除任何其他读取或写入

      【讨论】:

        猜你喜欢
        • 2017-07-01
        • 2018-05-23
        • 1970-01-01
        • 2014-12-04
        • 2011-01-21
        • 1970-01-01
        • 2010-09-16
        • 2010-12-17
        • 2012-06-05
        相关资源
        最近更新 更多