Коммуникация между параллельными потоками

Общие принципы, проектирование, модуляризация, темплейты и шаблоны
Аватара пользователя
Михаил23
adviser
adviser
Сообщения: 219
Зарегистрирован: 24 ноя 2008, 17:58
Версия LabVIEW: 2009
Откуда: Москва

Re: Коммуникация между параллельными потоками

Сообщение Михаил23 »

mzu2006 писал(а):IMHO, вместо notifier, там могла бы быть и queue.
Вот тут как раз и вопрос. Почему notifier, а не queue. В чем разница? Когда что использовать?
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение mzu2006 »

Когда важно лишь последнее значение. Или факт того, что значение было изменено (м.б. больше 1 раза) с момента последнего прочтения.
toto

Activity Gold Black
professional
professional
Сообщения: 390
Зарегистрирован: 07 мар 2008, 09:26
Награды: 3
Версия LabVIEW: 6i-16
Откуда: Санкт-Петербург
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение toto »

Сам сейчас занят этой проблемой. Правда я использовал не очереди и не нотифаеры в начале а USER EVENTS, это мне показалось удобнее тем, что в каждом своем модуле я могу в одной структуре EVENTS отлавливать сообщения от разных потоков. Надо наверное отметить, что я не реализовывал унифицированное событие для передачи любых данных, то есть под разные структуры я создавал отдельные события. Все прекрасно работает с User Event до тех пор, пока какой-нибудь модуль (поток) не начинает обрабатывать данные медленнее чем они поступают. Это в простом случае, на деле же там еще возникает сложность с тем, что в одном цикле я получаю сразу несколько типов событий и у каждого из них происходит обработка какая-то, и если одна из обработок подвисла, то остальные события начинают собираться в очередь, которая реализована внутри межанизма USER EVENTS и которую нельзя контролировать и обрабатывать. В итоге, ПО зависает с переполнением памяти. Натолкнувшись на эту проблему, я стал искать выход, поскольку из условно 30 типов событий у меня 3-4 события привязаны к "непрерывному" режиму (для примера, непрерывное считывание сигнала со звуковой карты для последующей записи/передачи по сети/ сжатия в MP3 и т. п.) то стало понятно, что надо обезопасить ПО от накопления этих данных в неуправляемых очередях. Не буду вдаваться в подробности, есть варианты которые позволяют сделать это и с использованием USER EVENTS, но выход нашелся гораздо более прозаический, а именно использование NOTIFICATION как раз!

Что же нам дает NOTIFICATION?
1) Добывающий поток (генерирующий поток) шлет эти самые NOTIFICATION с той скоростью с которой получает сигнал внезависимости от работы потоков которые обрабатывают эти данные.
2) Каждый поток который получает сигнал для обработки работает с той скоростью, с которой он может работать при этом если одному потоку надо накопить сигнал длительностью 1 с, он делает это потом кидает накопленый сигнал в алгоритм обработки и может игнорировать поступающие NOTIFICATION во время обработки (при этом нет никакой очереди и нет отставания от Real-Time)
Есть просто пропуск непрерывного сигнала между этапами обработки.
Если же нам требуется именно непрерывный режим обработки, то тут никуда ни деться надо обеспечивать скорострельность алгоритма обработки. Пример - сжатие в mp3, допустим модуль получает команду "НАЧАТЬ ЗАПИСЬ" с этого момента он перестает игнорировать NOTIFICATION и поступающий сигнал отправляет на сжатие.

PS Чего-то много я понаписал, чего раньше за собой не наблюдал, так что может есть немного сумбурности.
Аватара пользователя
Михаил23
adviser
adviser
Сообщения: 219
Зарегистрирован: 24 ноя 2008, 17:58
Версия LabVIEW: 2009
Откуда: Москва

Re: Коммуникация между параллельными потоками

Сообщение Михаил23 »

Нет ли у Вас примера что бы проиллюстрировать пункты 1) и 2) А то что то не очень врубился... :think:
toto

Activity Gold Black
professional
professional
Сообщения: 390
Зарегистрирован: 07 мар 2008, 09:26
Награды: 3
Версия LabVIEW: 6i-16
Откуда: Санкт-Петербург
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение toto »

Выкладываю пример:

Прошу конструктивно покритиковать!
Вложения
потоки.rar
Файл обновился !!!
(185.61 КБ) 433 скачивания
Последний раз редактировалось toto 27 фев 2010, 11:39, всего редактировалось 1 раз.
Аватара пользователя
Eugen Graf

Activity Professionalism Silver Black
guru
guru
Сообщения: 6502
Зарегистрирован: 13 ноя 2007, 02:20
Награды: 4
Версия LabVIEW: 2009
Откуда: Saarbrücken
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение Eugen Graf »

Я пример не смотрел, но вышеописаной ситуации возникать не должно по двум причинам:
1. программист должен заранее избегать таких ситуаций - поток, отправляющий данные в другой поток либо работает медленнее, либо собирает данные и уменьшает их количество например с помощью усреднения.
2. в крайнем случае можно установить определённый размер очереди, тем самым заставить отправляющий цикл заморозиться, при переполнении.
toto

Activity Gold Black
professional
professional
Сообщения: 390
Зарегистрирован: 07 мар 2008, 09:26
Награды: 3
Версия LabVIEW: 6i-16
Откуда: Санкт-Петербург
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение toto »

Евгений, нельзя запрещать передатчику слать, так как остальные приемники продолжают работать в штатном режиме.
А по поводу программист должен, да, должен конечно, но в моем случае ПО работало часов 6 непрерывно с полной нагрузкой нормально, потом в таблицах результатов накапливалось до 8000-10000 записей и обработка этих таблиц подгружала процессор до уровня в 80-90%, вот тут и начинались проблемы с потоками, когда просто алгоритмам обработки не хватало процессорного времени. Именно поэтому я стал искать пути обхода проблемы при использовани User Events. И теперь когда я искуственно заставил алгоритм обработки таблицы работать порциями и отдавать процессор на другие задачи и перевел систему на нотифаеры, ситуация улучшилась существенно.
Pavel

Activity
developer
developer
Сообщения: 271
Зарегистрирован: 31 июл 2009, 08:07
Награды: 1
Версия LabVIEW: 8.5

Re: Коммуникация между параллельными потоками

Сообщение Pavel »

toto писал(а):Евгений, нельзя запрещать передатчику слать, так как остальные приемники продолжают работать в штатном режиме.
А по поводу программист должен, да, должен конечно, но в моем случае ПО работало часов 6 непрерывно с полной нагрузкой нормально, потом в таблицах результатов накапливалось до 8000-10000 записей и обработка этих таблиц подгружала процессор до уровня в 80-90%, вот тут и начинались проблемы с потоками, когда просто алгоритмам обработки не хватало процессорного времени. Именно поэтому я стал искать пути обхода проблемы при использовани User Events. И теперь когда я искуственно заставил алгоритм обработки таблицы работать порциями и отдавать процессор на другие задачи и перевел систему на нотифаеры, ситуация улучшилась существенно.
Ну так запрети тому который подвис. :D
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение Helga »

Мне хочется посоветоваться по поводу NOTIFICATION.
Т.к. мне достались чужие программы, пока изучила т.д. Думаю, что NOTIFICATION используются не по делу.
Программа "Сборщик данных" передает данные через NOTIFICATION. Для хранения и передачи данных используется промежуточный функционал с регистрами. В него при старте "Сборщика данных" передаются указатели на NOTIFICATION.
По моей логике, "Сборщик данных" посылает сообщение, а функционал принимает. А сейчас сообщение посылается и тут же из "Сборщик данных" вызывается функционал с модусом "читать". А зачем, когда он может независимо переодически принимать сообщения. Необязательно функционалу давать внешнюю команду - прими сообщение. Или уж не использовать в таком случае NOTIFICATION. Как-то он излишен.

Я эти вопросы обсуждаю, т.к. естественно, не очень самоуверенный человек. :cry: Писали все эти программы умные мужики и мне очень сложно критически на готовый код смотреть. Вдруг чего не понимаю.
Последний раз редактировалось Helga 20 мар 2010, 10:58, всего редактировалось 1 раз.
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение mzu2006 »

Если я правильно понял ситуацию, то здесь избыточен функционал (Functional global), а notifer нужно поменять на очередь. Возможно, имеет смысл создать отдельный поток, который накапливает данные. Сказать сложно, пока не узнаешь больше о конкретике. Вообще, Functional global некоторые люди называют Anti-Pattern, т.е. шаблон дизайна, которого не следует придерживаться (lavag.org)
Helga
user
user
Сообщения: 89
Зарегистрирован: 14 мар 2010, 10:14
Версия LabVIEW: 9
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение Helga »

Функционал, по-моему мнению, тоже совершенно избыточен. Функционал в данном случае - :vi: с While Loop с регистрами. Одна программа записывает данные, другая считывает.
Получается, что сейчас notifier используется просто как кластер. В него как вариант данные записываются, потом он же передается при вызове в функционал.
Но можно же просто в программе, зная указатель на notifer, снимать с него сообщение и все.
Вопрос, если сообщение прочитано, оно изчезает или остается до следующего.

В моей программе совершенно не важно, пропали данные или нет. Они так часто снимаются с приборов, что некоторые приборы выдают старые измерения. Т.е. прибор измерят давление раз в минуту, а целую минуту идут старые данные. Я пыталась говорить, типа давайте раз в минуту и будим опрашивать, но хотят так. Хотят так хотят.
Аватара пользователя
Eugen Graf

Activity Professionalism Silver Black
guru
guru
Сообщения: 6502
Зарегистрирован: 13 ноя 2007, 02:20
Награды: 4
Версия LabVIEW: 2009
Откуда: Saarbrücken
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение Eugen Graf »

Возможно в данном случае этот проект программировали несколько человек. Дело в том, что почти все профессиональные программисты разделяются на две категории:
1. используют палитру синхронизации и параллельные потоки (к ним отношусь я)
2. используют функциональные глобальные переменные (в основном деды из прошлого, привыкшие к FGV)

Ну и есть третья категория, но скорее новичков, которые используют просто переменные (локальные, глобальные или же расшаренные).
Аватара пользователя
Eugen Graf

Activity Professionalism Silver Black
guru
guru
Сообщения: 6502
Зарегистрирован: 13 ноя 2007, 02:20
Награды: 4
Версия LabVIEW: 2009
Откуда: Saarbrücken
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение Eugen Graf »

Кстати вышла новая улучшенная версия библиотеки Tasking для коммуникации между параллельными потоками:
http://labviewportal.org/viewtopic.php?f=23&t=2078
Аватара пользователя
piznyur_alex
beginner
beginner
Сообщения: 43
Зарегистрирован: 11 фев 2010, 14:24
Версия LabVIEW: 2010
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение piznyur_alex »

Здравствуйте. Есть такая ситуация. Есть два параллельных потока ПОТОК 1 и ПОТОК 2. ПОТОК 1 отправляет данные в ПОТОК 2. В какой момент данные появятся в конце очереди ПОТОКА 2? Я так понимаю в момент новой итерации ПОТОКА 2? И в какой момент в ПОТОКЕ 2 обновляются глобальные переменные?
Спасибо.
Аватара пользователя
mzu2006

Professionalism Tutorials Black
doctor
doctor
Сообщения: 2456
Зарегистрирован: 16 авг 2008, 02:12
Награды: 3
Версия LabVIEW: 7.1 10 11 12
Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
Контактная информация:

Re: Коммуникация между параллельными потоками

Сообщение mzu2006 »

Путаница:
piznyur_alex писал(а):В какой момент данные появятся в конце очереди ПОТОКА 2?
очередь не принадлежит потоку. Я попробую ответить на смежные вопросы, а ты скажи попал я или нет, хорошо?

В очереди они появятся сразу после добавления.
Когда данные обработает поток 2? Тогда, когда дойдёт очередь выполняться до узла Dequeue Element.
piznyur_alex писал(а):в какой момент в ПОТОКЕ 2 обновляются глобальные переменные?
глобальные переменные опять таки не принадлежат потоку. Содержимое переменной обновится сразу после записи.
Когда они поток их прочитает? тогда, когда дойдёт до узла Global Variable.
Ответить

Вернуться в «Модели программирования»