互斥锁定仅写入

时间:2009-10-21 16:21:02

标签: c++ linux multithreading mutex

我有一个多线程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

困扰我的是:这意味着,我在阅读时必须锁定树(以避免在我阅读时启动垃圾收集)。然而 - 作为一种副作用 - 我也不能同时拥有两个阅读过程。

有什么建议吗?

是否有某种“这只是一种只与写作相冲突的只读动作”Mutex?

4 个答案:

答案 0 :(得分:10)

查看read-write-lock

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

答案 1 :(得分:4)

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

答案 2 :(得分:3)

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

答案 3 :(得分:0)

在C ++ 17中,std::shared_mutex直接支持这种类型的访问(多次读取,一次写入)。我认为这是从boost :: shared_lock采纳的。 Anthony Williams的《 C ++并发行动》中的示例也描述了该主题。 https://livebook.manning.com/book/c-plus-plus-concurrency-in-action-second-edition/chapter-3/185

基本位是:

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