2010-10-01 4 views
3

Я знаю, что есть ответы на подобные вопросы, но я задаю этот вопрос, поскольку они точно не дают того, что я хотел бы знать. Речь идет о синхронизации между потоками. Идея моего проекта заключается в том, что мы получаем данные с карты сбора данных и планируем и анализируем данные во время сбора данных. Пока у меня есть класс для сбора данных в одном потоке и класс для построения на другом потоке. Класс сбора данных хранит данные в глобальном кольцевом буфере, а сюжетный класс копирует данные из глобального буфера и выполняет некоторые процессы для построения графика (сокращение точки данных и т. Д.). Это то, что я называю одной (единственной) проблемой производителя (одного) потребителя. Мне удалось выполнить эту часть, используя два семафора, которые отслеживают, сколько точек данных хранится классом приобретения и сколько из них используется классом построения.Совместное использование массива данных среди потоков-C++

Теперь я хотел бы ввести еще один класс в другой поток, который анализирует данные. Тогда у меня будет один производитель и два потребителя. Я хотел бы наложить следующие условия:

  1. У двух считывателей есть один и тот же набор данных. I., каждый произведенный товар должен использоваться обоими считывателями, , а не только одним из них.
  2. Когда буфер заполняется, класс сбора данных перезаписывает глобальный буфер. Когда ридера (ы) теряют данные из-за перезаписи буфера по классу приобретения данных, это должно быть обнаружено и, в идеале, хранится в журнале (например, какая часть данных пропущен по readear (s)).
  3. Расчет анализа класс может быть интенсивным. Для этого Мне может понадобиться больший буфер данных в классе .

Способ, которым я занимался с первой частью (единственным производителем и единственным потребителем), как представляется, не распространяется на случай второй части (одного производителя и двух потребителей) простым способом. Мне интересно, как я должен действовать. Я использую C++ с Qt для потоковой обработки, так как я использую Qt для GUI. Но решение не обязательно должно быть с Qt. Однако, если это возможно, примеры кода или псевдокодов будут оценены с большой благодарностью. Я нашел аналогичную тему для своей проблемы here). Предлагается использовать boost :: interprocess. Однако, так как я никогда раньше не использовал библиотеку Boost и, хотя я читал документы об boost :: interprocess, он выглядит слишком вовлеченным, чтобы разобраться в себе.

Большое спасибо!

Daisuke

ответ

2

Если оба потребители должны видеть все элементы данных, вы, вероятно, лучше с буфером на потребителя. Затем производитель может отправлять одни и те же данные в каждый буфер. Если вас беспокоит потребность в памяти для дублирования данных таким образом, и данные не изменяются потребителями, тогда вы можете использовать указатель подсчета ссылок, такой как boost::shared_ptr, и отправлять указатель на данные в каждый буфер. Таким образом, элемент данных является общим, но читатели могут обрабатывать данные независимо.

Должно быть довольно тривиально, чтобы журнал производителей перезаписывал некоторые данные.

+0

Спасибо за ответ. До сих пор память не вызывает большого беспокойства. Итак, я начну с буфера для каждого потребителя. Что бы вы предлагали использовать для буфера на одного потребителя? Одна вещь, о которой я могу думать, это очередь в STL и queue :: push() данные от производителя и queue :: pop данные после использования потребителем. Будет ли это хорошей идеей? Одно дело было бы в том, что мой продюсер создавал кусок данных за один раз (около 10000 элементов двойного или целого числа). Если я буду стоять в очереди :: push(), каждый элемент будет немного медленным? Благодаря! – Daisuke

+0

Если ваш продюсер создает кусок элементов сразу, нажмите их как кусок. Поскольку это очередь с одним потребителем, потребитель может убедиться, что он обрабатывает элементы в куске в правильном порядке. –

+0

Будет ли очередь в STL позволять мне нажимать элементы как кусок? или Должен ли я наследовать класс и создать функцию-член для этого? Если это так, как бы вы это сделали? – Daisuke

0

Я думаю, вы должны прочитать следующие статьи параллелизм Herb Sutter, чтобы почувствовать, как вы должны структурировать и как быть масштабируемым (если это цель). Ссылка ниже - последняя статья, но также содержит полный список предыдущих.

http://herbsutter.com/2010/09/24/effective-concurrency-know-when-to-use-an-active-object-instead-of-a-mutex/

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

http://herbsutter.com/2008/05/23/effective-concurrency-maximize-locality-minimize-contention/

+0

Спасибо за предложение. Создание копий данных - хорошая идея. Я размышлял о том, как обернуть все в мьютексах. Спасибо также за ссылку на статью. Статьи выглядят немного плотными для меня. Но я потрачу некоторое время на их чтение. Надеюсь, я могу увеличить зрелость при одновременном программировании. – Daisuke

Смежные вопросы