Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Алгоритм, один производитель два потребителя  (Прочитано 14010 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
pokk
Помогающий

ru
Offline Offline

« : 23-03-2017 04:51 » 

Есть три модуля, первый принимает данные и складывает в кольцевой буфер, второй и третий модуль достает данные из буфера и один записывает данные в файл,другой выдает их напрямую. Так вот как правильно сделать синхронизацию второго и третьего модуля ? Что бы они дожидались друг друга.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 23-03-2017 05:02 » 

pokk, пусть буфер содержит элементы типа T.  Добавь в T два флага - "записан в файл" , "передан напрямую". Любой из двух читающих модулей обрабатывает элемент и выставляет свой флаг (если флаг уже был выставлен, то обработка уже не требуется). Любой модуль, увидевший, что у элемента все флаги выставлены, удаляет элемент из буфера
Записан

pokk
Помогающий

ru
Offline Offline

« Ответ #2 : 23-03-2017 06:21 » 

Спасибо за  ответ, а как примерно будет выглядит  код у потребителя на си ?
У меня получилось что в одном потребителе это будет так а другом GetFlagFile   GetFlagOut местами буду поменяны, правда мне это как раз и не нравится что как-то не едино все получается.
Код:
if(GetFlagFile()){  //Если стоит флаг обработки "записан в файл" (в GetFlagFile сбросить его)  
//Записать в файл
if(!GetFlagOut()){ //Если нету флага обработки "передан напрямую"   
Удалить из буфера
Достать следуюший элементы (и установить флаги на обработку)
}
}

Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 23-03-2017 07:34 » 

а зачем нужна синхронизация второго с третьим модулем? или наоборот? они ж наверное для того и сделаны чтоб разделить ...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
pokk
Помогающий

ru
Offline Offline

« Ответ #4 : 23-03-2017 08:33 » 

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

PS: А задача простая надо просто принять и записать некий сигнал  , и что бы было видно как он записывается, делаю одновременный вывод его.
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 23-03-2017 09:01 » new

Потребителям нет никакой необходимости ждать друг друга.

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

Типовой паттерн проектирования Wire Tap.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 23-03-2017 09:13 » 

pokk,
Что бы данные доставались из кольцевого буфера одни, как для второго модуля так и для третьего.
И в случае если в кольцевом буфере находится больше одной порции данных, не получилась так что, второй модуль обе порции записал, когда третий модуль только одну порцию выдал.

PS: А задача простая надо просто принять и записать некий сигнал  , и что бы было видно как он записывается, делаю одновременный вывод его.

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

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
pokk
Помогающий

ru
Offline Offline

« Ответ #7 : 23-03-2017 10:11 » 

Dale, я так понял что бы сделать вторую очередь придется копировать данные ? Это копирование не когда мне не нравится, видать по этому и парюсь с такими вопросами, пока подумываю настроить прием данных сразу в две очереди.
Ochkarik, так вот то что произойдет быстрее, а эта запись  она в 20 раз быстрее чем передача сигнала, то в случае если  в очереди было несколько пакетов на запись то они спокойно запишутся, и удалятся из очереди пока "Передатчик" отправляет один пакет, и после того как он выдаст его он потеряет несколько пакетов. Да возможно я сделал  не совсем правильно кольцевой буфер, но сначала делал с расчетом на одного потребителя, по этому и сделал всего  3 функции:
1) положить в буфер.
2) достать из буфера(и там сразу удаление из очереди происходит). 
3) Выдать количество пакетов в очереди.
Пытался минимизировать количество функций что бы в основном алгоритме не городить, удаление из очереди и тд, а то потом происходит сильное загромождение его и сложно  разбираться. 
 
PS:  Считываю сигнал по байтно, но потом формирую его в пакеты по  300 байт, и именно их и буферизирую, точнее их адреса.
 

 
Записан
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 23-03-2017 11:39 » 

что бы сделать вторую очередь придется копировать данные ?

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

С кольцевым буфером тоже можно работать параллельно - один указатель для производителя и два отдельных для каждого потребителя. Пусть каждый потребитель, обработав данные, передвигает свой личный указатель на шаг.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 23-03-2017 13:40 » 

да, два указателя/индекса и все будет хорошо.

PS удобно делать на атомарных инкрементах/декрементах

PPS две переменные - количество необработанного. читать и писать по кольцу хоть побайтно хоть поблочно.
при записи инкремент обоих, при чтении декремент.
при записи можно тестировать оба на переполнение буфера
при чтении читать пока не станет нулевым(данные кончились)
« Последнее редактирование: 23-03-2017 13:51 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 23-03-2017 13:51 » 

А мне вот интересно зайти с другой стороны...
Запись в файл - зачем? Для того, чтобы потом смотреть-анализировать, видимо. Ну, или на "аварийный" случай.
Велика ли важность, насколько синхронно данные будут "писаться" в файл и передаваться? Пусть себе пишутся данные из своей очереди, важно, чтобы они все записались, а что там передалось на отображение (я так понял) - через секунду-две оператор уже может и не вспомнить... А в файле все есть - берите и смотрите...
Так что я пока в принципе не вижу такой необходимости чтобы "...не получилась так что, второй модуль обе порции записал, когда третий модуль только одну порцию выдал..."
Может я задачу недопонял... Но вариант распихать данные в 2 очереди - на запись и на передачу мне кажется вполне разумным.
« Последнее редактирование: 23-03-2017 13:56 от Михалыч » Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 23-03-2017 21:18 » 

А какой синхронизации идет речь?

Что и как там принимает первый модуль все равно
Его задача выставить lock на время записи

Т.е. грубо - реализация транзакций в базах

Если все же есть необходимость в реал тайме - типа, некогда ждать, надо отдать, и забыть

То под каждую транзакцию выделяется буфера, заведомо больший входных данных
И первый модуль сам разруливает своим внутренними ресурсами

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 23-03-2017 21:35 » 

Я бы использовал счетчик ссылок на объект. Последний release удаляет объект или как-то иначе утилизирует. Изначально счетчик равен единице. При постановке в очередь (очередь указателей) увеличиваем его на единицу. После постановки уменьшаем на единицу. Каждый потребитель после обработки уменьшает счетчик на единицу. Если, к примеру, какой-то потребитель захочет поставить указатель в очередь другому потребителю, то счетчик не меняем. В этой схеме объект живет ровно пока он нужен. Создавший его производитель может и не знать о его дальнейшей судьбе.

Реализация счетчика через методы (или функции, если это Си). В методах использовать атомарные операции инкремента/декремента. Эти же методы отвечают за утилизацию объекта.
« Последнее редактирование: 23-03-2017 21:37 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 24-03-2017 04:39 » 

pokk, насколько я понял, у тебя приоритет - это запись в файл. А передачу сигнала для просмотра делай редко, скажем не чаще, чем раз в  200 мс. Для оператора это равносильно регулятору FPS на экране, но зато можно больше ресурсов отдать под сохранение сигнала в файл. И таки да, две очереди лучше

если неразрывность "показа" сигнала необходима, можно накапливать "кадр" и передавать раз в 200 мс пакет
« Последнее редактирование: 24-03-2017 04:41 от Алексей++ » Записан

pokk
Помогающий

ru
Offline Offline

« Ответ #14 : 24-03-2017 09:40 » 

Спасибо всем за советы, пока остановился на том что прием сигнала будет производиться сразу в две очереди.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines