多个生产者,单个消费者

我必须开发一个multithreading应用程序,其中将有多个线程,每个线程生成自定义事件日志并需要保存在队列中保存(不是微软MSMQ)。

将有另一个线程从队列中读取日志数据并使用某些信息对其进行操作以将日志信息保存到文件中。基本上,我们在这里实现多个生成器单个消费者范例。

任何机构都可以建议我如何在C ++或C#中实现它。

谢谢,

使用System.Collections.Concurrent定义的BlockingCollection很容易做到这一点。

基本上,您创建队列以便所有线程都可以访问它:

 BlockingCollection LogQueue = new BlockingCollection(); 

每个生产者都将项添加到队列中:

 while (!Shutdown) { LogRecord rec = CreateLogRecord(); // however that's done LogQueue.Add(rec); } 

消费者做了类似的事情:

 while (!Shutdown) { LogRecord rec = LogQueue.Take(); // process the record } 

默认情况下, BlockingCollection使用ConcurrentQueue作为后备存储。 ConcurrentQueue负责线程同步,并且BlockingCollection在尝试获取项目时执行非忙等待。 也就是说,如果消费者在队列中没有项目时调用Take ,则在项目可用之前执行非忙碌等待(无睡眠/旋转)。

您可以使用同步队列 (如果您有.NET 3.5或更旧代码)或更好的新ConcurrentQueue

你计划的是一个经典的生产者消费者队列,其中一个线程消耗队列中的项目来完成一些工作。 这可以包含在一个称为“actor”或“active object”的更高级别的构造中。

基本上,这会将队列和使用项目的线程包装到单个类中,其他线程将此类上的所有异步方法都放在队列中的消息上,由actor的线程执行。 在您的情况下,类可以有一个方法writeData,它将数据存储在队列中,并触发条件变量以通知actor线程队列中有什么东西。 如果不在条件变量上等待,则actor线程会查看队列中是否有任何数据。

这是一篇关于这个概念的好文章:

http://www.drdobbs.com/go-parallel/article/showArticle.jhtml;jsessionid=UTEXJOTLP0YDNQE1GHPSKH4ATMY32JVN?articleID=225700095

多个生产者,单个消费者是multithreading队列通信的最简单方案。 线程队列可以实现为条件变量/互斥锁和std :: queue的组合(如果要处理队列已满,则添加cv)。

当队列为空时,消费者在cv上等待。 生成器在添加到队列(发送)时发出信号。