User Event

Обсуждение, связанное с разработкой ПО верхнего уровня
Ответить
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

User Event

Сообщение IvanLis »

Кто использует в своих проектах User Event подскажите насколько они надежны и как правильно их использовать.
По идее User Event должно дойти до всех приемников, которые должны ее обработать.
Но при работе возникает баг, который хорошо воспроизводится (OS-Linux, LV2016 64-bit).
Сделал два цикла обрабатывающих одно и тоже событие, по нажатии кнопки next, значение должно быть увеличено на 1.
Но при последовательности нажатий с разной частотой, количество зарегистрированных событий одним приемником отличается от другого.
В реальном проекте события будут обрабатываться в разных SubVI, по этому обычный Event не подходит.
Кто, что посоветует?
UserEvent-lv2016.vi
(21.59 КБ) 179 скачиваний
UserEvent-lv2010 save from 2016.vi
(12.72 КБ) 174 скачивания
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: User Event

Сообщение IvanLis »

Добавил классическую обработку события в оба цикла. Получается, что событие вообще может быть не обработано :cry:
Снимок экрана от 2018-08-25 09-08-53.png
Пока вывод: использовать User Event для передачи важных сообщений и информации нельзя, т.к. возможен пропуск события!
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: User Event

Сообщение dadreamer »

Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: User Event

Сообщение IvanLis »

dadreamer, огромное спасибо!
Все не так плохо, как мне показалось.
Если регистрировать события для каждого обработчика отдельно, то все работает без пропусков.
Попробовал даже с 1ms интервалом запустить.
One Reg User Event -> Fault
One Reg User Event -> Fault
Individual Reg User Event -> Ok
Individual Reg User Event -> Ok
1ms User Event -> Ok
1ms User Event -> Ok
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: User Event

Сообщение dadreamer »

IvanLis писал(а):Кто использует в своих проектах User Event подскажите насколько они надежны и как правильно их использовать.
Я время от времени использую их в своих программах. Не так, чтобы супер часто (всё-таки очереди и уведомители - number 1), но порой пригождаются. Например, для передачи событий из главного :vi: в подпрограммы, где также крутятся Event структуры. Ни разу нареканий к ним не имел (при условии правильного использования, конечно). :)

ЗЫ: для нижнего цикла Unregister тоже нужен.
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: User Event

Сообщение IvanLis »

dadreamer писал(а):для нижнего цикла Unregister тоже нужен.
Ага, переделывал, упустил...

Я всегда Queue использую, там удобно и последовательностью управлять и если что просмотреть все элементы в буфере можно.
Бывают пустяковые задачи, но для которых приходится создавать несколько очередей (для каждой SubVI), потом из основного цикла посылать сообщение каждой очереди индивидуально... И все только ради нескольких событий GUI, на которые отзыв всех (или) нескольких SubVI.
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: User Event

Сообщение dadreamer »

IvanLis писал(а):Бывают пустяковые задачи, но для которых приходится создавать несколько очередей (для каждой SubVI), потом из основного цикла посылать сообщение каждой очереди индивидуально... И все только ради нескольких событий GUI, на которые отзыв всех (или) нескольких SubVI.
Можно сделать две очереди - в одну сторону (в SubVI) и в другую (в Main VI). А в самом сообщении прописывать адресата. Например, "Прибор1:График1:Очистка". Spreadsheet String в этом случае очень помогает. Те SubVI, кому это не предназначено, просто проигнорируют.

А насчёт UE: можно, конечно, заменить их на очередь или уведомитель с логическим параметром. Но иногда бывает нужно, чтобы событие было отловлено именно в Event Structure, а не в каком-то постороннем цикле While (например, работа с (G)UI, чтобы все Property/Invoke Nodes находились в одном месте и не переключали в UI Thread другие циклы).
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: User Event

Сообщение IvanLis »

dadreamer писал(а):Можно сделать две очереди - в одну сторону (в SubVI) и в другую (в Main VI). А в самом сообщении прописывать адресата. Например, "Прибор1:График1:Очистка". Spreadsheet String в этом случае очень помогает. Те SubVI, кому это не предназначено, просто проигнорируют.
С одной стороны логично, но... :think:
А есть какой-нибудь пример "учебно-боевой", а то не совсем понятна идея.

Если использовать для чтения Dequeue Element, потом его анализировать и если он не предназначен для данного цикла (SubVI), дублировать его снова в очередь... В этом случае нарушается очередность команд, да и когда он дойдет до адресата неизвестно.

Более правильно, это просматривать элемент перед его чтением используя Preview Queue Element, анализировать и в случае совпадения адресатов делать Dequeue Element. В этом случае цикл обрабатывающий сообщения поступающие с низкой интенсивностью будет получать их с большой задержкой (пока не подойдет его сообщение, а это может быть через 1000 элементов). Ну и парсить команды приходится неоднократно.

Можно конечно использовать Get Queue Status, просматривать всю очередь в поиске своего сообщения, но удалить конкретный элемент из очереди нельзя (я по крайней мере не знаю как), а если очищать очередь и повторно в нее отправлять все ненужные (предназначенные другим циклам).... это тоже не малые накладные расходы, да и возникает задержка в доставке. Да и не исключена ситуация, что между считыванием всех элементов очереди до ее очистки, какой-нибудь из циклов выдернет из нее сообщение и обработает, а потом обработает еще раз (после ретранслции) ... и как это обернется х.з.

И в конце концов, если потребуется остановить N циклов, то все равно придется отправлять каждому команду индивидуально, только в одной очереди.
Blackman

Activity
leader
leader
Сообщения: 932
Зарегистрирован: 17 янв 2016, 15:02
Награды: 1
Версия LabVIEW: 6.1,8.5,20

Re: User Event

Сообщение Blackman »

Это уже было лет 6 тому назад): LabVIEW User Events Tips, Tricks, and Sundry
https://github.com/wirebirdlabs/LabVIEW ... and-Sundry
Один пример из этой презентации.
Вложения
04 - Demonstration - Effect of Branching Event Registration.vi
LabVIEW 2013
(22.92 КБ) 202 скачивания
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: User Event

Сообщение dadreamer »

IvanLis писал(а):Можно конечно использовать Get Queue Status, просматривать всю очередь в поиске своего сообщения, но удалить конкретный элемент из очереди нельзя (я по крайней мере не знаю как), а если очищать очередь и повторно в нее отправлять все ненужные (предназначенные другим циклам).... это тоже не малые накладные расходы, да и возникает задержка в доставке.
Ну, если в программе не несколько сотен циклов и на каждый не приходится по паре сотен команд, то будет вполне себе исправно работать. (В списке команд можно выбрать несколько пунктов с помощью клавиши Ctrl).
Queue_Cmd.vi
lv2016
(32.27 КБ) 179 скачиваний
Циклы достаточно быстро разбирают сообщения, если конечно их не нагрузить какими-нибудь "тяжёлыми" операциями, чтобы само по себе не очень правильно. Ну, понятно, что на каждый цикл своя очередь - более элегантный и простой подход. Или можно сделать строковый UE вместо очереди и не парить мозг.
IvanLis писал(а):Да и не исключена ситуация, что между считыванием всех элементов очереди до ее очистки, какой-нибудь из циклов выдернет из нее сообщение и обработает, а потом обработает еще раз (после ретранслции) ... и как это обернется х.з.
Можно поставить семафор на подобный случай (см. пример). Хотя :labview: внутри как-то всё равно разделяет одновременный доступ к одной очереди (м.б., мьютекс ставится, не копался).
IvanLis писал(а):И в конце концов, если потребуется остановить N циклов, то все равно придется отправлять каждому команду индивидуально, только в одной очереди.
Именно для остановки циклов я уже много лет применяю логический уведомитель. Никогда не подводил. Изредка (в асинхронно вызываемых SubVI) использую логический UE, т.к. иногда бывает нужно остановить/закрыть SubVI чуть раньше, чем остановится Main VI.
Blackman

Activity
leader
leader
Сообщения: 932
Зарегистрирован: 17 янв 2016, 15:02
Награды: 1
Версия LabVIEW: 6.1,8.5,20

Re: User Event

Сообщение Blackman »

Есть такая библиотека -
NI Qbus v1.0.0.2 by National Instruments
Released On: Thu, 19 May 2016 16:26:03 -0500
Author: National Instruments
Copyright: Copyright (c) 2016, National Instruments
License: NI Sample Code License
Compatible LabVIEW Versions: >= 2015.
Compatible OS Versions: ALL.
Repository Name: NI LabVIEW Tools Network
Description:
NI Qbus is a LabVIEW based messaging API. The library provides VIs for sharing messages between asynchronous processes. The Qbus API provides subVIs that allow processes to send two types of messages:
Broadcast messages—Available to any process. The sender does not specify a recipient for a broadcast message. To receive a specific type of broadcast message, each process registers for the messages it desires by name.
Routed messages—Sent only to a specific, named process. You might send a routed message when multiple processes register for a particular message name, but in a specific situation, you only want one specific process to receive and handle the message.

Пример ее применения (первоисточник от dadreamer ) :wink:
Вложения
Blackman--Qbus_Example.png
Blackman--Qbus_Example.vi
(49.74 КБ) 180 скачиваний
Аватара пользователя
Kosist

Activity Gold
expert
expert
Сообщения: 1236
Зарегистрирован: 21 фев 2011, 23:44
Награды: 2
Версия LabVIEW: 2013-2020
Благодарил (а): 23 раза
Поблагодарили: 30 раз
Контактная информация:

Re: User Event

Сообщение Kosist »

IvanLis писал(а):Кто использует в своих проектах User Event подскажите насколько они надежны и как правильно их использовать.
Ни разу не испытывал проблем с ними. Терять пакеты они в принципе не могут, т.к. User Event работает как и очередь, по принципу FIFO. Но, Вам уже и так сказали, что было неправильно в том примере...
Их отлично применять тогда, когда надо делать broadcast сообщения - например, остановка всех модулей; т.к. User Event может иметь Multiple Writers/Multiple Readers, в то время как для корректной работы очереди нужно иметь лишь одного "читателя".
В своих проектах я их использую для остановки Helper Loop в акторах - родительский актор содержит инициализацию юзер-события в Pre-Launch Init.vi; в Stop Core.vi посылается сообщения, а затем ссылка закрывается; и эта же ссылка доступна во всех дочерних классах - если нужно, можно "вытянуть" ее, и использовать для остановки цикла в Actor Core.vi.
Есть еще крутая библиотека Stream, при помощи которой можно делать абстракцию любого основного канала передачи данных в :labview:.
Мы делили апельсин - много наших полегло...
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: User Event

Сообщение IvanLis »

Blackman писал(а):Есть такая библиотека -
NI Qbus v1.0.0.2 by National Instruments
Это ближе к "телу".
Посмотрел исходники, там в принципе неявно для пользователя создаются отдельные очереди для каждого процесса (Listener Process), что позволяет исключить все недостатки о которых я ранее писал.
Добавить пару функций в стиле Enqueue Element At Opposite End для широковещательной и индивидуальной рассылки и будет совсем хорошо.
Останется один минус, это то что команды в String, а не Enum Type Def которые позволяют исключить ряд ошибок.
Аватара пользователя
taras_33

Activity
professional
professional
Сообщения: 391
Зарегистрирован: 31 окт 2009, 18:25
Награды: 1
Версия LabVIEW: 2019
Поблагодарили: 13 раз
Контактная информация:

Re: User Event

Сообщение taras_33 »

родительский актор содержит инициализацию юзер-события в Pre-Launch Init.vi; в Stop Core.vi посылается сообщения, а затем ссылка закрывается;
Такой же техникой пользуюсь и я.
Создаем...
Pre Launch.png
Pre Launch.png (6.25 КБ) 6651 просмотр
Генерируем событие, останавливая циклы с user event - ами
Stop Core.png
Stop Core.png (5.11 КБ) 6651 просмотр
Все "детки" и старшие и младшие наследуются от этого класса. Достаточно удобно.
Есть еще крутая библиотека Stream
Библиотека действительно крутая 130 мб весит
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
Blackman

Activity
leader
leader
Сообщения: 932
Зарегистрирован: 17 янв 2016, 15:02
Награды: 1
Версия LabVIEW: 6.1,8.5,20

Re: User Event

Сообщение Blackman »

IvanLis писал(а): ...
Останется один минус, это то что команды в String, а не Enum Type Def которые позволяют исключить ряд ошибок.
Это осознанный выбор. Упрощает интеграцию Qbus c различными процессами, которые как правило имеют различные наборы команд. Как это делают в NI можно посмотреть например в следующих библиотеках (есть в VIPM):
NI Blink Process Library
https://forums.ni.com/t5/Reference-Desi ... -p/3537109
NI Timer Process Library
https://forums.ni.com/t5/Reference-Desi ... -p/3537108
Если есть предпочтение использования Enum Type Def, то достаточно в библиотеке процесса сделать wrappers для Qbus :vi: c Enum Type Def на входе и выходе.
Для отлова ошибок команд (не реализована, ошибки синтаксиса и т.д.), как правило используется Default case. Но например в NI Timer Process Library это правило не выполняется :dntknw:
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Лицевая панель»