.NET 4包含新的并发数据结构。 Bag和Dictionary集合有明显的应用程序,但我看不到Queue和Stack数据结构的任何用途。人们使用这些是为了什么?
另外,我注意到基于链表的设计会产生大量的分配并破坏可扩展性。鉴于这些集合的唯一目的是多核编程,这是令人惊讶的。这是一个固有的限制还是刚刚实施得很糟糕?
答案 0 :(得分:11)
堆栈和队列在并发编程中非常有用,就像顺序编程一样。
新的ConcurrentQueue<T>
和ConcurrentStack<T>
类提供了一个非常好的,线程安全的Queue和Stack实现。这些在处理多线程生产者/消费者场景时特别有用,因为这两个类都是无锁的(有利于可伸缩性)和线程安全,并且性能相当高。
另外,我想指出一件事 - 你的第二段有两个误解。链接列表对于可伸缩性并不是特别糟糕。内存分配〜可能需要定期发生(虽然有办法解决这个问题),但通常情况下,这比可扩展性方面的其他潜在问题要小。 (这实际上取决于场景......)此外,新的ConcurrentQueue<T>
和ConcurrentStack<T>
类不基于(至少是传统的)链接列表。它们是一个无锁类,在内部使用链接的数组列表来保存元素,更像是std::deque。
答案 1 :(得分:3)
队列的一个相当明显的场景是将一个(或多个)线程放入队列中的工作项,以及几个工作线程提取它们以进行并发处理。
我认为基于链表的设计是为了让它无锁。它的可扩展性有什么问题,你有哪些其他选择?
答案 2 :(得分:2)
这里最近的一篇博文文章详细介绍了您所关注的问题(使用ConcurrentBag和TPL的GC问题),提出了在现场发现和分析此问题的方法(VS2010 Concurrency Visualizer)。建议使用Server GC进行部分解决。
答案 3 :(得分:0)
解决问题的第二部分,你是完全正确的,虽然.Net 4.0中的并发集合实现试图无锁,但它们仍然位于无锁无内存分配子系统之上。
内存管理是所有无锁数据结构的祸根:这是一个关于最新技术的精彩演示: http://sysrun.haifa.il.ibm.com/hrl/ISMM2009/program.html#7
最重要的是,这个领域正在进行中,因此可能尚未准备好包含在广泛部署的生产平台中,例如.Net。