多个生产者,单个消费者

发布于 2024-10-19 04:36:56 字数 224 浏览 2 评论 0原文

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

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

任何人都可以提供有关如何在 C++ 或 C# 中实现此功能的建议吗?

谢谢,

I have to develop a multithreaded application, where there will be multiple threads, each thread generates custom event log which need to be saved in queue (not Microsoft MSMQ).

There will be another thread which reads log data from queue and manipulates it, with certain information to save log information into a file. Basically here we are implementing Multiple-producer, Single-consumer paradigm.

Can anybody provide suggestions on how to implement this in C++ or C#.

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

贱贱哒 2024-10-26 04:36:56

使用 可以很容易地完成这种事情BlockingCollectionSystem.Collections.Concurrent 中定义。

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

BlockingCollection<LogRecord> LogQueue = new BlockingCollection<LogRecord>();

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

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,它将执行非繁忙等待(不休眠/旋转),直到有项目可用。

This kind of thing is very easy to do using the BlockingCollection<T> defined in System.Collections.Concurrent.

Basically, you create your queue so that all threads can access it:

BlockingCollection<LogRecord> LogQueue = new BlockingCollection<LogRecord>();

Each producer adds items to the queue:

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

And the consumer does something similar:

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

By default, BlockingCollection uses a ConcurrentQueue<T> as the backing store. The ConcurrentQueue takes care of thread synchronization and, and the BlockingCollection does a non-busy wait when trying to take an item. That is, if the consumer calls Take when there are no items in the queue, it does a non-busy wait (no sleeping/spinning) until an item is available.

故事灯 2024-10-26 04:36:56

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

You can use a synchronized queue (if you have .NET 3.5 or older code) or even better the new ConcurrentQueue<T>!

煮茶煮酒煮时光 2024-10-26 04:36:56

您正在计划的是一个经典的生产者消费者队列,其中一个线程消耗队列上的项目来完成一些工作。这可以被包装到称为“参与者”或“活动对象”的更高级别的构造中。

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

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

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

What you are planning is a classic producer consumer queue with a thread consuming the items on the queue to do some work. This can be wrapped into is a higher level construct called an "actor" or "active object".

Basically this wraps the queue and the thread that consumes the items into a single class, the other threads all asynchronous methods on this class with put the messages on the queue to be performed by the actor's thread. In your case the class could have a single method writeData which stores the data in the queue and triggers the condition variable to notify the actor thread that there is something in the queue. The actor thread sees if there is any data in the queue if not waits on the condition variable.

Here is a good article on the concept:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文