【问题标题】:List insertion, disjoint n parallel?列表插入,不相交n平行?
【发布时间】:2010-11-15 18:03:56
【问题描述】:

我一直在搜索允许并发插入到列表中不相交位置的并发链表实现/学术论文。我更喜欢基于锁的方法。

不幸的是,到目前为止,我检查过的所有实现都使用基于列表的锁定,而不是类似于基于节点的锁定。

有帮助的人吗?

编辑 1:感谢大家最初的回复。使用基于节点的锁定意味着要在节点之后插入或删除节点,我需要锁定上一个和下一个节点。现在完全有可能,当线程 1 尝试锁定前一个节点时,它在线程 2 中被删除了。如何防范此类事故?

【问题讨论】:

    标签: c multithreading pthreads


    【解决方案1】:

    我无法推荐任何专门为 C 执行此操作的库,但如果您最终自己执行此操作,您可能会通过重用少量锁和一些“散列”来避免拥有数千个锁" 来决定每个节点使用哪个。在很多情况下,如果锁的数量适当地大于节点的数量以减少空间开销(并且它是固定的,而不是每个节点),则不会有任何争用。

    为 EDIT 1 更新

    您可以通过为每个列表设置多个读取器、单个写入锁 (rwlock) 来解决此问题,您可以在获取每个节点锁之前获取“读取”锁用于插入,但用于删除您需要获得单个“写”锁。您可以很容易地避免读取/插入操作的不必要的同步问题,并且删除也很简单。 (假设是删除比插入少得多)

    【讨论】:

    • 谢谢,我这边 +1。我一直在考虑类似的问题,但我有我现在在问题(编辑 1)中提到的问题。请回复。
    • 添加了我对该问题的建议。其他人推荐的无锁数据结构变得越来越普遍,它们非常好,但很难(正确)推出自己的数据结构。
    • 在正常遍历列表时,您还需要对每个列表 rwlock 进行读取锁定,以防止您正在查看的节点从您下方删除。跨度>
    • 有趣的策略。但是,这肯定会减慢通常的节点搜索过程,因为如果并行发生插入,我们不能随机遍历列表。
    【解决方案2】:

    您可能想看看使用无锁实现。这个想法是在插入/删除节点时使用原子测试集操作。

    不幸的是,广为人知的实现并不多。你可能不得不自己动手。这是关于原子操作支持的 gcc 文档:

    http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html

    【讨论】:

      【解决方案3】:

      基于节点的锁定的问题是您通常必须为每次插入锁定两个节点。在某些情况下,这可能会更昂贵。

      更糟糕的是,你会遇到和哲学家一样的僵局,你必须处理这种可能性。

      因此,基于列表的锁定更容易,这就是为什么您会看到更多关于这些的信息。

      如果基于列表的锁定的性能特征不利于您的应用程序,请考虑更改为与单链表不同的数据结构。

      【讨论】:

      • 单链表可以避免死锁吗?新节点不需要锁定,因为没有其他人可以知道它的存在,只有一个节点需要调整其“下一个”指针以使其工作。
      • 我不认为请哲学家吃饭是一件令人担心的事,因为这份名单是井井有条的,而不是循环的。
      • @awoodland:Q 没有提到列表是否单独链接,@Eric 也没有提到它不是循环的。当然你可以避免僵局,但你必须小心,这就是我所说的。
      猜你喜欢
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-24
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多