Несколько производителей, один потребитель - PullRequest
9 голосов
/ 24 февраля 2011

Мне нужно разработать многопоточное приложение, в котором будет несколько потоков, каждый поток генерирует собственный журнал событий и должен быть сохранен в сохраненной в очереди (не в Microsoft MSMQ).

Будет еще один поток, которыйчитать данные журнала из очереди и манипулировать ими с определенной информацией, чтобы сохранить информацию журнала в файл. В основном, здесь мы реализуем единственную парадигму потребителя с несколькими производителями.

Может ли кто-нибудь предложить мне, как реализовать это в C ++ или C #.

Спасибо,

Ответы [ 4 ]

10 голосов
/ 24 февраля 2011

Подобные вещи очень легко сделать, используя BlockingCollection<T>, определенный в System.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<T> в качестве резервного хранилища,ConcurrentQueue заботится о синхронизации потоков и, а BlockingCollection делает незанятое ожидание при попытке получить элемент.То есть, если потребитель вызывает Take, когда в очереди нет элементов, он делает незанятое ожидание (без спящего / вращающегося), пока элемент не станет доступным.

2 голосов
/ 24 февраля 2011

То, что вы планируете, - это классическая очередь потребителя-производителя с потоком, потребляющим элементы в очереди для выполнения некоторой работы. Это может быть включено в конструкцию более высокого уровня, называемую «субъект» или «активный объект».

По существу, это оборачивает очередь и поток, который потребляет элементы, в один класс, а остальные потоки - все асинхронные методы этого класса с помещением сообщений в очередь для выполнения потоком субъекта. В вашем случае у класса может быть один метод writeData, который хранит данные в очереди и запускает переменную условия, чтобы уведомить поток актера о том, что в очереди что-то есть. Поток субъекта видит, есть ли какие-либо данные в очереди, если не ожидает переменную условия.

Вот хорошая статья о концепции:

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

2 голосов
/ 24 февраля 2011

Вы можете использовать синхронизированную очередь (если у вас есть .NET 3.5 или более старый код) или даже лучше, новый ConcurrentQueue<T>!

1 голос
/ 24 февраля 2011

Несколько производителей, один потребитель - самый простой сценарий для многопоточной связи в очереди.Потоковая очередь может быть реализована как комбинация условной переменной / мьютекса и std :: queue (добавьте cv, если вы хотите обработать очередь полной).

Потребитель ждет cv, пока очередьпустой.сигнал производителей при добавлении в очередь (отправка).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...