我正在尝试在c ++中设计一个允许并发访问的链表。显然,对于该列表使用单个锁是非常低效的,因为可以并行更新不相交的区域。现在除了每个节点存储一个锁之外,还有什么选择?
另外,在这种情况下,非阻塞版本会更好吗?任何相关链接,任何人?
编辑:感谢您的回复。我想补充一些事情:
答案 0 :(得分:4)
答案 1 :(得分:2)
Linked lists are inherently sequential data structures.无论您使用何种机制来实现它,接口和预期行为都意味着顺序逻辑。
你想做什么?这应该决定您使用的数据结构,而不是您熟悉的数据结构的熟悉程度。
答案 2 :(得分:1)
根据您将如何使用该列表,您可以采用多种不同的方式。
首先,对于列表,单个互斥锁不一定是大问题,因为列表可以支持拼接。假设您有一个字符AF列表和另一个列表BCDE。您不必锁定互斥锁,插入B,再次锁定它,插入C等。您可以通过将A的下一个指针设置为B而将E的下一个指针设置为F,从而在A和F之间一次性插入BCDE,从而形成ABCDEF。无论您想要一次插入多少元素,您只需要一个锁。即使对于双重链表也是如此。因此,它可能不是您应用程序中的瓶颈。
假设它会成为瓶颈,你需要考虑你是否会有一个或多个作家以及一个或多个读者。
假设您有一个编写器和多个读取器,您可以完全通过使用原子指令来避免互斥锁,假设它们可用于您的体系结构。在GCC中,这些可以通过内置的__sync_ *函数获得,在Visual C ++中它们可以通过Interlocked *获得,但如果您遇到缺乏对它们的直接支持的编译器,您仍然可以通过内联汇编使用它们。编写器将使用原子指令以原子方式设置列表中的补丁元素的下一个指针。
希望这能让你开始。为了得到一个深刻的答案,我建议提出另一个问题,包括:
答案 3 :(得分:0)
你确定这是一个值得解决的问题吗?将实际最终用法封装到处理普通list
锁定的类中并提供线程安全接口可能更有用吗?这样你就不会试图把锁定放在一个太低的水平上(正如你猜测的那样,这不是一个容易解决的问题)。
答案 4 :(得分:0)
跳过列表怎么样?看看“并发”包中的java实现。