并发队列和堆栈在.NET 4中的应用

时间:2010-06-15 23:24:38

标签: c# .net f# concurrency

.NET 4包含新的并发数据结构。 Bag和Dictionary集合有明显的应用程序,但我看不到Queue和Stack数据结构的任何用途。人们使用这些是为了什么?

另外,我注意到基于链表的设计会产生大量的分配并破坏可扩展性。鉴于这些集合的唯一目的是多核编程,这是令人惊讶的。这是一个固有的限制还是刚刚实施得很糟糕?

4 个答案:

答案 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进行部分解决。

http://blogs.msdn.com/b/hshafi/archive/2010/06/17/case-study-parallelism-and-memory-usage-vs2010-tools-to-the-rescue.aspx?wa=wsignin1.0

答案 3 :(得分:0)

解决问题的第二部分,你是完全正确的,虽然.Net 4.0中的并发集合实现试图无锁,但它们仍然位于无锁无内存分配子系统之上。

内存管理是所有无锁数据结构的祸根:这是一个关于最新技术的精彩演示: http://sysrun.haifa.il.ibm.com/hrl/ISMM2009/program.html#7

最重要的是,这个领域正在进行中,因此可能尚未准备好包含在广泛部署的生产平台中,例如.Net。