На паре ресурсов эта информация вызвала интерес и даже небольшие споры. Я подумал, что полезно поделиться знаниями и тут.
Очереди можно использовать «неправильно»
Мы же знаем, что очередь — это «первый пришёл — первый ушёл» (FIFO), и есть строгое правило: один или несколько производителей → один (и только один) потребитель. Это связано с тем, что при чтении элемента он удаляется из очереди, поэтому последующие попытки чтения будут неудачными. Возможно ли использовать очередь в сценарии одного производителя → множества потребителей?
Несколько лет назад у нас была задача распараллелить ресурсоёмкие вычисления: АЦП получал данные, которые нужно было прогнать через сложные алгоритмы. Был многопроцессорный серверный ПК, CPU был загружен на несколько процентов, но вычисления всё равно отставали и система не справлялась с потоком данным. Проблема была в том, что вычисления не были параллельными.
Несколько параллельных циклов решали проблему параллельности, но как организовать распределение задач? Как producer должен понять, в какую очередь отправить новую порцию данных? Флаги, обратная связь «я завершил вычисления»? Новые усложнения архитектуры. фуфуфу.
В итоге мы нашли элегантное решение. Каждый элемент из очереди можно забрать ровно один раз. Именно это нам и нужно! Один производитель и много потребителей. Как только один из экземпляров обработчика завершает очередной цикл, он встаёт в очередь на… чтение очереди.
По сути LabVIEW за нас занималось диспетчеризацией потоков.
В простом варианте это просто N параллельных циклов/SubVI. Если хочется чуть больше универсальности и привязать количество циклов к количеству процессоров, то можно запускать вычислители с помощью call-by-ref.
Так что, как говорили у нас в школе: если нельзя, но очень хочется, то можно.
Нестандартное использование очередей
-
IvanLis
- guru

- Сообщения: 5696
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 35 раз
- Поблагодарили: 129 раз
Нестандартное использование очередей
Давай тогда я тоже перенесу обсуждение из Tg сюда, может кому пригодится.
Я несколько раз использовал очереди не по назначению, а для организации своеобразного "конвейера" - "псевдо параллельность".
Т.е. разбиваешь сложную вычислительную задачу на шаги. Каждый шаг выполняется в своем цикле.
Получается, так:
Первый цикл получает порцию данных, выполняется первый шаг, отправляется во второй цикл и освобождается, что позволяет принять следующую порцию данных.
Второй цикл получил данные, вычислил, отправил дальше. И т.д.
Например у нас шесть шагов (циклов), когда первый получает седьмую порцию, последний досчитывает первую
.
И если правильно декомпозировать задачу, то можно распределить вычисления между потоками.
Так и последовательность данных не нарушается, когда это важно и вычисления ведутся параллельно.
Вот пример и результаты тестирования:
Ubuntu 24.04lts + LV2026Q1 Видно, что в первом случае задача выполняется на одном ядре.
Во втором, сначала одно ядро, потом подключается второе и т.д.
Разница во времени более чем в 2 раза.
Windows 7 (VirtualBox) + LV2015
Я несколько раз использовал очереди не по назначению, а для организации своеобразного "конвейера" - "псевдо параллельность".
Т.е. разбиваешь сложную вычислительную задачу на шаги. Каждый шаг выполняется в своем цикле.
Получается, так:
Первый цикл получает порцию данных, выполняется первый шаг, отправляется во второй цикл и освобождается, что позволяет принять следующую порцию данных.
Второй цикл получил данные, вычислил, отправил дальше. И т.д.
Например у нас шесть шагов (циклов), когда первый получает седьмую порцию, последний досчитывает первую
И если правильно декомпозировать задачу, то можно распределить вычисления между потоками.
Так и последовательность данных не нарушается, когда это важно и вычисления ведутся параллельно.
Вот пример и результаты тестирования:
Ubuntu 24.04lts + LV2026Q1 Видно, что в первом случае задача выполняется на одном ядре.
Во втором, сначала одно ядро, потом подключается второе и т.д.
Разница во времени более чем в 2 раза.
Windows 7 (VirtualBox) + LV2015
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение Картинку или Файл
Как добавить в сообщение Видео
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение Картинку или Файл
Как добавить в сообщение Видео
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
-
Artem.spb
- professor

- Сообщения: 3666
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 64 раза
- Поблагодарили: 204 раза
- Контактная информация:
Re: Нестандартное использование очередей
Если уж не то пошло, ты используешь очередь по назначению: для передачи данных из одного цикла в другойIvanLis писал(а): 18 авг 2026, 14:02 Я несколько раз использовал очереди не по назначению, а для организации своеобразного "конвейера" - "псевдо параллельность".
-
IvanLis
- guru

- Сообщения: 5696
- Зарегистрирован: 02 дек 2009, 17:44
- Награды: 7
- Версия LabVIEW: 2015, 2016
- Откуда: СССР
- Благодарил (а): 35 раз
- Поблагодарили: 129 раз
Re: Нестандартное использование очередей
СогласенArtem.spb писал(а): 18 авг 2026, 15:05 Если уж не то пошло, ты используешь очередь по назначению: для передачи данных из одного цикла в другой![]()
Знание нескольких принципов освобождает от знания многих фактов!
Правила форума
Как добавить в сообщение Картинку или Файл
Как добавить в сообщение Видео
Конвертация / версий (форматов) VI
Как правильно задать вопрос...
Правила форума
Как добавить в сообщение Картинку или Файл
Как добавить в сообщение Видео
Конвертация / версий (форматов) VI
Как правильно задать вопрос...