【问题标题】:C++ thread safe doubly linked listC++线程安全双向链表
【发布时间】:2010-09-13 08:34:31
【问题描述】:

我正在编写的应用程序需要上述数据结构。我想知道是否有一个库已经实现了它,还是我必须自己编写它?

如果没有必要,我真的不想重新发明轮子。

我需要这个结构能够使用多个线程添加和删除项目,而不必在这样做时锁定整个结构。

【问题讨论】:

  • 你能写出你真正需要的结构操作吗?也许您并不真的需要双链表,而其他结构也可以工作?
  • 你想要多线程安全?您想从任意线程写入任意位置?
  • 您要求添加和删除的速度有多快?乍一看,它似乎是一个哈希表可能对你有用。可扩展的线程安全哈希表很常见 - 只需搜索一些即可。
  • 这个数据结构在任何时候都可能包含相当多的项目,所以它应该很快。这是一个服务器应用程序,有许多客户端。
  • 删除项目以进行处理。

标签: c++ windows data-structures


【解决方案1】:

可能有,但我认为这是 Java 早期学到的经验之一——数据同步性通常不在容器的成员函数级别,而是在上一步。您应该在访问非线程安全列表之前使用同步对象。

考虑:

ThreadSafeQueue tsq;
tsq.push_back(...); // add lots of data

...

// Find the first element that returns true for search_criteria(elem);
auto iter = tsq.find_if(search_criteria); 
// (1)                                  
if(iter != tsq.end()) // (2)
{
    tsq.erase(iter);
}

在这个线程安全的队列中,还有两个“空隙”可以让另一个线程更改队列。而且,确实,您的迭代器可能会因这些更改而失效。现在比较:

Queue q;
q.push_back(...); // add lots of data

...

// Create some lock around a pre-existing mutex.
Lock lock(q_mutex);
// Find the first element that returns true for search_criteria(elem);
auto iter = q.find_if(search_criteria); 

if(iter != q.end())
{
    q.erase(iter);
}
// lock unlocks as it goes out of scope.

这里,因为锁的粒度比较大,所以可以保证跨写算法的一致性。

【讨论】:

    【解决方案2】:

    相关研究链接:Is a lock (wait) free doubly linked list possible?

    由于您没有请求无锁容器,因此我没有将其标记为完全重复。

    注意:虽然接口和性能特征看起来像一个双链表,但在内部,这些结构非常复杂,基于哈希表或其他结构。没有什么东西可以在内部建立一个双链表,并且同时是无锁的。我不记得看过证明,但我认为这是不可能的。


    根据您的附加信息,我认为您根本不需要双链表。您可以使用Windows API single linked list instead。添加使用InterlockedPushEntrySList,删除使用InterlockedPopEntrySList。

    【讨论】:

    • 是的! InterlockedSLists 非常快,并且已经内置到操作系统中
    【解决方案3】:
    【解决方案4】:

    关于使用汇编/编译器内部函数编写无锁队列来执行原子操作的论文很多,但要让它工作起来真的很困难。

    所以如果你可以使用锁,也许可以使用这样的东西:Concurrent FIFO Queue with Boost

    【讨论】:

      猜你喜欢
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 2020-06-28
      相关资源
      最近更新 更多