Вот тут как раз и вопрос. Почему notifier, а не queue. В чем разница? Когда что использовать?mzu2006 писал(а):IMHO, вместо notifier, там могла бы быть и queue.
Коммуникация между параллельными потоками
- Михаил23
- adviser
- Сообщения: 219
- Зарегистрирован: 24 ноя 2008, 17:58
- Версия LabVIEW: 2009
- Откуда: Москва
Re: Коммуникация между параллельными потоками
-
mzu2006
- doctor
- Сообщения: 2456
- Зарегистрирован: 16 авг 2008, 02:12
- Награды: 3
- Версия LabVIEW: 7.1 10 11 12
- Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
- Контактная информация:
Re: Коммуникация между параллельными потоками
Когда важно лишь последнее значение. Или факт того, что значение было изменено (м.б. больше 1 раза) с момента последнего прочтения.
Правила форума (Forum rules in Russian)
rm -rf /mnt/windows
rm -rf /mnt/windows
-
- professional
- Сообщения: 390
- Зарегистрирован: 07 мар 2008, 09:26
- Награды: 3
- Версия LabVIEW: 6i-16
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Коммуникация между параллельными потоками
Сам сейчас занят этой проблемой. Правда я использовал не очереди и не нотифаеры в начале а 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 Чего-то много я понаписал, чего раньше за собой не наблюдал, так что может есть немного сумбурности.
Что же нам дает NOTIFICATION?
1) Добывающий поток (генерирующий поток) шлет эти самые NOTIFICATION с той скоростью с которой получает сигнал внезависимости от работы потоков которые обрабатывают эти данные.
2) Каждый поток который получает сигнал для обработки работает с той скоростью, с которой он может работать при этом если одному потоку надо накопить сигнал длительностью 1 с, он делает это потом кидает накопленый сигнал в алгоритм обработки и может игнорировать поступающие NOTIFICATION во время обработки (при этом нет никакой очереди и нет отставания от Real-Time)
Есть просто пропуск непрерывного сигнала между этапами обработки.
Если же нам требуется именно непрерывный режим обработки, то тут никуда ни деться надо обеспечивать скорострельность алгоритма обработки. Пример - сжатие в mp3, допустим модуль получает команду "НАЧАТЬ ЗАПИСЬ" с этого момента он перестает игнорировать NOTIFICATION и поступающий сигнал отправляет на сжатие.
PS Чего-то много я понаписал, чего раньше за собой не наблюдал, так что может есть немного сумбурности.
- Михаил23
- adviser
- Сообщения: 219
- Зарегистрирован: 24 ноя 2008, 17:58
- Версия LabVIEW: 2009
- Откуда: Москва
Re: Коммуникация между параллельными потоками
Нет ли у Вас примера что бы проиллюстрировать пункты 1) и 2) А то что то не очень врубился...
-
- professional
- Сообщения: 390
- Зарегистрирован: 07 мар 2008, 09:26
- Награды: 3
- Версия LabVIEW: 6i-16
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Коммуникация между параллельными потоками
Выкладываю пример:
Прошу конструктивно покритиковать!
Прошу конструктивно покритиковать!
- Вложения
-
- потоки.rar
- Файл обновился !!!
- (185.61 КБ) 435 скачиваний
Последний раз редактировалось toto 27 фев 2010, 11:39, всего редактировалось 1 раз.
-
Eugen Graf
- guru
- Сообщения: 6502
- Зарегистрирован: 13 ноя 2007, 02:20
- Награды: 4
- Версия LabVIEW: 2009
- Откуда: Saarbrücken
- Контактная информация:
Re: Коммуникация между параллельными потоками
Я пример не смотрел, но вышеописаной ситуации возникать не должно по двум причинам:
1. программист должен заранее избегать таких ситуаций - поток, отправляющий данные в другой поток либо работает медленнее, либо собирает данные и уменьшает их количество например с помощью усреднения.
2. в крайнем случае можно установить определённый размер очереди, тем самым заставить отправляющий цикл заморозиться, при переполнении.
1. программист должен заранее избегать таких ситуаций - поток, отправляющий данные в другой поток либо работает медленнее, либо собирает данные и уменьшает их количество например с помощью усреднения.
2. в крайнем случае можно установить определённый размер очереди, тем самым заставить отправляющий цикл заморозиться, при переполнении.
-
- professional
- Сообщения: 390
- Зарегистрирован: 07 мар 2008, 09:26
- Награды: 3
- Версия LabVIEW: 6i-16
- Откуда: Санкт-Петербург
- Контактная информация:
Re: Коммуникация между параллельными потоками
Евгений, нельзя запрещать передатчику слать, так как остальные приемники продолжают работать в штатном режиме.
А по поводу программист должен, да, должен конечно, но в моем случае ПО работало часов 6 непрерывно с полной нагрузкой нормально, потом в таблицах результатов накапливалось до 8000-10000 записей и обработка этих таблиц подгружала процессор до уровня в 80-90%, вот тут и начинались проблемы с потоками, когда просто алгоритмам обработки не хватало процессорного времени. Именно поэтому я стал искать пути обхода проблемы при использовани User Events. И теперь когда я искуственно заставил алгоритм обработки таблицы работать порциями и отдавать процессор на другие задачи и перевел систему на нотифаеры, ситуация улучшилась существенно.
А по поводу программист должен, да, должен конечно, но в моем случае ПО работало часов 6 непрерывно с полной нагрузкой нормально, потом в таблицах результатов накапливалось до 8000-10000 записей и обработка этих таблиц подгружала процессор до уровня в 80-90%, вот тут и начинались проблемы с потоками, когда просто алгоритмам обработки не хватало процессорного времени. Именно поэтому я стал искать пути обхода проблемы при использовани User Events. И теперь когда я искуственно заставил алгоритм обработки таблицы работать порциями и отдавать процессор на другие задачи и перевел систему на нотифаеры, ситуация улучшилась существенно.
Re: Коммуникация между параллельными потоками
Ну так запрети тому который подвис.toto писал(а):Евгений, нельзя запрещать передатчику слать, так как остальные приемники продолжают работать в штатном режиме.
А по поводу программист должен, да, должен конечно, но в моем случае ПО работало часов 6 непрерывно с полной нагрузкой нормально, потом в таблицах результатов накапливалось до 8000-10000 записей и обработка этих таблиц подгружала процессор до уровня в 80-90%, вот тут и начинались проблемы с потоками, когда просто алгоритмам обработки не хватало процессорного времени. Именно поэтому я стал искать пути обхода проблемы при использовани User Events. И теперь когда я искуственно заставил алгоритм обработки таблицы работать порциями и отдавать процессор на другие задачи и перевел систему на нотифаеры, ситуация улучшилась существенно.
-
- user
- Сообщения: 89
- Зарегистрирован: 14 мар 2010, 10:14
- Версия LabVIEW: 9
- Контактная информация:
Re: Коммуникация между параллельными потоками
Мне хочется посоветоваться по поводу NOTIFICATION.
Т.к. мне достались чужие программы, пока изучила т.д. Думаю, что NOTIFICATION используются не по делу.
Программа "Сборщик данных" передает данные через NOTIFICATION. Для хранения и передачи данных используется промежуточный функционал с регистрами. В него при старте "Сборщика данных" передаются указатели на NOTIFICATION.
По моей логике, "Сборщик данных" посылает сообщение, а функционал принимает. А сейчас сообщение посылается и тут же из "Сборщик данных" вызывается функционал с модусом "читать". А зачем, когда он может независимо переодически принимать сообщения. Необязательно функционалу давать внешнюю команду - прими сообщение. Или уж не использовать в таком случае NOTIFICATION. Как-то он излишен.
Я эти вопросы обсуждаю, т.к. естественно, не очень самоуверенный человек. Писали все эти программы умные мужики и мне очень сложно критически на готовый код смотреть. Вдруг чего не понимаю.
Т.к. мне достались чужие программы, пока изучила т.д. Думаю, что NOTIFICATION используются не по делу.
Программа "Сборщик данных" передает данные через NOTIFICATION. Для хранения и передачи данных используется промежуточный функционал с регистрами. В него при старте "Сборщика данных" передаются указатели на NOTIFICATION.
По моей логике, "Сборщик данных" посылает сообщение, а функционал принимает. А сейчас сообщение посылается и тут же из "Сборщик данных" вызывается функционал с модусом "читать". А зачем, когда он может независимо переодически принимать сообщения. Необязательно функционалу давать внешнюю команду - прими сообщение. Или уж не использовать в таком случае NOTIFICATION. Как-то он излишен.
Я эти вопросы обсуждаю, т.к. естественно, не очень самоуверенный человек. Писали все эти программы умные мужики и мне очень сложно критически на готовый код смотреть. Вдруг чего не понимаю.
Последний раз редактировалось Helga 20 мар 2010, 10:58, всего редактировалось 1 раз.
-
mzu2006
- doctor
- Сообщения: 2456
- Зарегистрирован: 16 авг 2008, 02:12
- Награды: 3
- Версия LabVIEW: 7.1 10 11 12
- Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
- Контактная информация:
Re: Коммуникация между параллельными потоками
Если я правильно понял ситуацию, то здесь избыточен функционал (Functional global), а notifer нужно поменять на очередь. Возможно, имеет смысл создать отдельный поток, который накапливает данные. Сказать сложно, пока не узнаешь больше о конкретике. Вообще, Functional global некоторые люди называют Anti-Pattern, т.е. шаблон дизайна, которого не следует придерживаться (lavag.org)
Правила форума (Forum rules in Russian)
rm -rf /mnt/windows
rm -rf /mnt/windows
-
- user
- Сообщения: 89
- Зарегистрирован: 14 мар 2010, 10:14
- Версия LabVIEW: 9
- Контактная информация:
Re: Коммуникация между параллельными потоками
Функционал, по-моему мнению, тоже совершенно избыточен. Функционал в данном случае - с While Loop с регистрами. Одна программа записывает данные, другая считывает.
Получается, что сейчас notifier используется просто как кластер. В него как вариант данные записываются, потом он же передается при вызове в функционал.
Но можно же просто в программе, зная указатель на notifer, снимать с него сообщение и все.
Вопрос, если сообщение прочитано, оно изчезает или остается до следующего.
В моей программе совершенно не важно, пропали данные или нет. Они так часто снимаются с приборов, что некоторые приборы выдают старые измерения. Т.е. прибор измерят давление раз в минуту, а целую минуту идут старые данные. Я пыталась говорить, типа давайте раз в минуту и будим опрашивать, но хотят так. Хотят так хотят.
Получается, что сейчас notifier используется просто как кластер. В него как вариант данные записываются, потом он же передается при вызове в функционал.
Но можно же просто в программе, зная указатель на notifer, снимать с него сообщение и все.
Вопрос, если сообщение прочитано, оно изчезает или остается до следующего.
В моей программе совершенно не важно, пропали данные или нет. Они так часто снимаются с приборов, что некоторые приборы выдают старые измерения. Т.е. прибор измерят давление раз в минуту, а целую минуту идут старые данные. Я пыталась говорить, типа давайте раз в минуту и будим опрашивать, но хотят так. Хотят так хотят.
-
Eugen Graf
- guru
- Сообщения: 6502
- Зарегистрирован: 13 ноя 2007, 02:20
- Награды: 4
- Версия LabVIEW: 2009
- Откуда: Saarbrücken
- Контактная информация:
Re: Коммуникация между параллельными потоками
Возможно в данном случае этот проект программировали несколько человек. Дело в том, что почти все профессиональные программисты разделяются на две категории:
1. используют палитру синхронизации и параллельные потоки (к ним отношусь я)
2. используют функциональные глобальные переменные (в основном деды из прошлого, привыкшие к FGV)
Ну и есть третья категория, но скорее новичков, которые используют просто переменные (локальные, глобальные или же расшаренные).
1. используют палитру синхронизации и параллельные потоки (к ним отношусь я)
2. используют функциональные глобальные переменные (в основном деды из прошлого, привыкшие к FGV)
Ну и есть третья категория, но скорее новичков, которые используют просто переменные (локальные, глобальные или же расшаренные).
-
Eugen Graf
- guru
- Сообщения: 6502
- Зарегистрирован: 13 ноя 2007, 02:20
- Награды: 4
- Версия LabVIEW: 2009
- Откуда: Saarbrücken
- Контактная информация:
Re: Коммуникация между параллельными потоками
Кстати вышла новая улучшенная версия библиотеки Tasking для коммуникации между параллельными потоками:
http://labviewportal.org/viewtopic.php?f=23&t=2078
http://labviewportal.org/viewtopic.php?f=23&t=2078
- piznyur_alex
- beginner
- Сообщения: 43
- Зарегистрирован: 11 фев 2010, 14:24
- Версия LabVIEW: 2010
- Контактная информация:
Re: Коммуникация между параллельными потоками
Здравствуйте. Есть такая ситуация. Есть два параллельных потока ПОТОК 1 и ПОТОК 2. ПОТОК 1 отправляет данные в ПОТОК 2. В какой момент данные появятся в конце очереди ПОТОКА 2? Я так понимаю в момент новой итерации ПОТОКА 2? И в какой момент в ПОТОКЕ 2 обновляются глобальные переменные?
Спасибо.
Спасибо.
-
mzu2006
- doctor
- Сообщения: 2456
- Зарегистрирован: 16 авг 2008, 02:12
- Награды: 3
- Версия LabVIEW: 7.1 10 11 12
- Откуда: St-Petersburg (RU), Phila, Boston, Washington DC
- Контактная информация:
Re: Коммуникация между параллельными потоками
Путаница:
В очереди они появятся сразу после добавления.
Когда данные обработает поток 2? Тогда, когда дойдёт очередь выполняться до узла Dequeue Element.
Когда они поток их прочитает? тогда, когда дойдёт до узла Global Variable.
очередь не принадлежит потоку. Я попробую ответить на смежные вопросы, а ты скажи попал я или нет, хорошо?piznyur_alex писал(а):В какой момент данные появятся в конце очереди ПОТОКА 2?
В очереди они появятся сразу после добавления.
Когда данные обработает поток 2? Тогда, когда дойдёт очередь выполняться до узла Dequeue Element.
глобальные переменные опять таки не принадлежат потоку. Содержимое переменной обновится сразу после записи.piznyur_alex писал(а):в какой момент в ПОТОКЕ 2 обновляются глобальные переменные?
Когда они поток их прочитает? тогда, когда дойдёт до узла Global Variable.
Правила форума (Forum rules in Russian)
rm -rf /mnt/windows
rm -rf /mnt/windows