Асинхронный вызов VI

Общие принципы, проектирование, модуляризация, темплейты и шаблоны
Аватара пользователя
Shamrel
beginner
beginner
Сообщения: 38
Зарегистрирован: 02 мар 2017, 12:15
Версия LabVIEW: 2015

Асинхронный вызов VI

Сообщение Shamrel »

Приветствую! Программирую на LabVIEW давно. И, как правило, все вопросы удавалось уладить с помощью хелпа и форумов.
Но сейчас гугл меня подвел. Суть проблемы в следующем.
В основной программе делаю вызов одного (или нескольких копий) подприборов (SubVI). Использую функцию "Start Asynchronous Call". Меня не устраивает режим "запустил и забыл", и ждать завершения SubVI тоже нельзя. SubVI должны выполнятся параллельно с основной программой (имеют свой интерфейс пользователя). Однако основная программа должна знать, как поживает потомок и совершать в связи с этим определенные действия.
Как в программе отследить состояние запущенных SubVI?
Сейчас ничего умнее чем, проверять в цикле состояние Front Panel (Property Node -> FP.State) и далее принимать уже, какое-либо решение я не придумал.
Еще костыль -- сделать уведомление на стороне SubVI перед закрытием, а в основной программе ждать этого сообщение. Все равно -- некрасиво.
Может быть есть способ автоматически отслеживать изменение по reference через структуру Event?

P.S.: Интуитивно я ищу что-то похожее на системный вызов select или pselect, как в системах POSIX.
Аватара пользователя
dadreamer

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

Re: Асинхронный вызов VI

Сообщение dadreamer »

Shamrel писал(а):Использую функцию "Start Asynchronous Call".
...
Как в программе отследить состояние запущенных SubVI?
Вложения
2017-03-02_16-04-24.jpg
Аватара пользователя
Shamrel
beginner
beginner
Сообщения: 38
Зарегистрирован: 02 мар 2017, 12:15
Версия LabVIEW: 2015

Re: Асинхронный вызов VI

Сообщение Shamrel »

"Wait On Asynchronous Call" -- Эта функция синхронно ждет завершение процесса. Она стопорит выполнение программы. Или я не до конца разобрался с ней?
Аватара пользователя
dadreamer

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

Re: Асинхронный вызов VI

Сообщение dadreamer »

Shamrel писал(а):"Wait On Asynchronous Call" -- Эта функция синхронно ждет завершение процесса. Она стопорит выполнение программы. Или я не до конца разобрался с ней?
Задаёте ей таймаут 50-100 мс (сколько у вас составляет задержка в цикле) и проверяете возвращаемую ошибку. Нет ошибки - SubVI закрылся, есть ошибка по таймауту - SubVI всё ещё работает. Все задержки, естественно, должны выполняться параллельно, чтоб время цикла не увеличивалось.
Аватара пользователя
Shamrel
beginner
beginner
Сообщения: 38
Зарегистрирован: 02 мар 2017, 12:15
Версия LabVIEW: 2015

Re: Асинхронный вызов VI

Сообщение Shamrel »

dadreamer писал(а): Задаёте ей таймаут 50-100 мс (сколько у вас составляет задержка в цикле) и проверяете возвращаемую ошибку. Нет ошибки - SubVI закрылся, есть ошибка по таймауту - SubVI всё ещё работает. Все задержки, естественно, должны выполняться параллельно, чтоб время цикла не увеличивалось.
Проблемы возникают, когда заранее неизвестно, сколько копий subVIE будут запущено -- для каждого SubVI нужно городить свою функцию "Wait On Asynchronous Call". Даже если сформировать массив референсов и опрашивать в цикле с нулевым таймаутом.
Да и сути не меняет. Так или иначе это опрос в цикле. В этом случае, предложенный мною способ не хуже:
Сканирование состояния
Сканирование состояния
Artem.spb

Activity Автор
professor
professor
Сообщения: 3393
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

Re: Асинхронный вызов VI

Сообщение Artem.spb »

в таком случае самое разумное в функции перед выходом отправлять оповещение, что работа окончена. Чем этот вариант не нравится?
Аватара пользователя
Shamrel
beginner
beginner
Сообщения: 38
Зарегистрирован: 02 мар 2017, 12:15
Версия LabVIEW: 2015

Re: Асинхронный вызов VI

Сообщение Shamrel »

Artem.spb писал(а):в таком случае самое разумное в функции перед выходом отправлять оповещение, что работа окончена. Чем этот вариант не нравится?
Программистский опыт протестует. Кривоватенько. Вдруг с потомком чего случилось до того, как он завершил свою работу корректным способом и не успел отправить сообщение?
Родитель должен иметь корректный механизм отслеживания состояния потомков. Сейчас безнадежно пытаюсь сделать динамическое событие на прерывание работы SubVI. Но, кажется, это не тот путь.
Artem.spb

Activity Автор
professor
professor
Сообщения: 3393
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 49 раз
Поблагодарили: 172 раза
Контактная информация:

Re: Асинхронный вызов VI

Сообщение Artem.spb »

Кривоватенько, это если VI может из-за ошибки вылететь, не оповестив никого. Если ошибки обрабатывать корректно, то таких проблем не будет.
Если уж доходить до паранойи, то вдруг с родителем что случится? :)
Shamrel писал(а): Сейчас безнадежно пытаюсь сделать динамическое событие на прерывание работы SubVI.
и что безнадёжно сложного в событиях, очередях и нотификаторах?
Аватара пользователя
dadreamer

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

Re: Асинхронный вызов VI

Сообщение dadreamer »

Shamrel писал(а):Проблемы возникают, когда заранее неизвестно, сколько копий subVIE будут запущено -- для каждого SubVI нужно городить свою функцию "Wait On Asynchronous Call".
А разве нельзя сделать одну реентерантную? У вас же SubVI однотипные, друг от друга не отличаются ничем. Так?
Shamrel писал(а):Даже если сформировать массив референсов и опрашивать в цикле с нулевым таймаутом.
Ну а что, решение как решение. Массив ссылок позволяет различить, в каком состоянии тот или иной SubVI, т.к. ссылка - штука уникальная. Так что вы всегда знаете, что случилось с вашими потомками.
Shamrel писал(а):В этом случае, предложенный мною способ не хуже
Не хуже. Его можно чуть упростить с помощью "Wait On Asynchronous Call". Ну, и у вас анализируется FP.State = Closed, но из-за чего ошибка произошла... :dntknw: Если уж совсем придираться.
Shamrel писал(а):Вдруг с потомком чего случилось до того, как он завершил свою работу корректным способом и не успел отправить сообщение?
Родитель должен иметь корректный механизм отслеживания состояния потомков.
А что вы хотите делать дальше с этой информацией? Просто в лог записать? Так у вас практически всё готово для этого. Если перезапуск - тоже, в принципе, ссылку только заменить в массиве.
Аватара пользователя
Shamrel
beginner
beginner
Сообщения: 38
Зарегистрирован: 02 мар 2017, 12:15
Версия LabVIEW: 2015

Re: Асинхронный вызов VI

Сообщение Shamrel »

Artem.spb писал(а):Кривоватенько, это если VI может из-за ошибки вылететь, не оповестив никого. Если ошибки обрабатывать корректно, то таких проблем не будет.
Если уж доходить до паранойи, то вдруг с родителем что случится? :)
Это не паранойя, это многолетний опыт разработки ПО для промышленности. Зачем лишний раз подставляться там, где этого можно избежать?
Поток может получить команду от операционной системы на срочное завершение и никакая система внутреннего контроля за ошибками тут не поможет (например, в unix системах это сигнал SIGKILL). Что касается пункта "то вдруг с родителем что случится? :)", то по какой-то прихоти разработчиков от NI, child завершает свою работу при гибели родителя. (Столкнулся с такой проблемой относительно недавно. )
Artem.spb писал(а):
Shamrel писал(а): Сейчас безнадежно пытаюсь сделать динамическое событие на прерывание работы SubVI.
и что безнадёжно сложного в событиях, очередях и нотификаторах?
А подскажите, как? Как сделать так, что бы структура event смогла фиксировать событие на изменение статуса асинхронно запущенного SubVI?

P.S.: Сильно смущает тот факт, что я не смог напрямую прикрутить очереди и уведомления к событийному механизму. Такое впечатление, что где-то не там копаю.
Черт возьми! Это же логично, что должна быть возможность сделать Event Case на приход сообщение в очереди! или нет? :suicide:
Аватара пользователя
dadreamer

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

Re: Асинхронный вызов VI

Сообщение dadreamer »

Shamrel писал(а):А подскажите, как? Как сделать так, что бы структура event смогла фиксировать событие на изменение статуса асинхронно запущенного SubVI?

P.S.: Сильно смущает тот факт, что я не смог напрямую прикрутить очереди и уведомления к событийному механизму. Такое впечатление, что где-то не там копаю.
Черт возьми! Это же логично, что должна быть возможность сделать Event Case на приход сообщение в очереди! или нет? :suicide:
А юзверь-events чем не угодили? :crazy:
Аватара пользователя
Shamrel
beginner
beginner
Сообщения: 38
Зарегистрирован: 02 мар 2017, 12:15
Версия LabVIEW: 2015

Re: Асинхронный вызов VI

Сообщение Shamrel »

dadreamer писал(а): А юзверь-events чем не угодили? :crazy:
Его же тоже в основном цикле формировать придется. -- те же яйца.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2210
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Асинхронный вызов VI

Сообщение Borjomy_1 »

Это же логично, что должна быть возможность сделать Event Case на приход сообщение в очереди! или нет?
Есть таймаут очереди при ожидании элемента в Dequeue Element. Работа с очередью происходит по событийному принципу. Чем вас не устраивает?

Есть также элемент Occurence. Его можно передавать при запуске экземляра и потом ожидать в основной программе. Либо наоборот: по передаваемому Occurence отдавать команду на останов экземпляра.

Для управления передавать экземпляру два нотифаера, либо один (в поле данных которого передавать ref нотифаера для ответа). Экземляр ловит нотифаер и отвечает по переданному ref необходимую информацию. управляющая программа дает команду и ждет ответа по отправленному refу. В случае превышения таймаута экземпляр можно грохать...
Последний раз редактировалось Borjomy_1 02 мар 2017, 17:54, всего редактировалось 1 раз.
Аватара пользователя
dadreamer

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

Re: Асинхронный вызов VI

Сообщение dadreamer »

Shamrel писал(а):
dadreamer писал(а): А юзверь-events чем не угодили? :crazy:
Его же тоже в основном цикле формировать придется. -- те же яйца.
Ну, как раз этим способом получаете, что хотели
Shamrel писал(а):что бы структура event смогла фиксировать событие на изменение статуса асинхронно запущенного SubVI
В одной Event-структуре можно будет и обрабатывать UI, и обрабатывать события из параллельно работающих саб-ВИ. Тип эвента можно задать как String, тогда в Саб-ВИ можно генерировать строку в формате "Ссылка (Ref, I32): Само событие (старт/стоп)". По Ref'у можно отследить, какой потомок в какое состояние перешёл. Минимум затрат от разработчика.
Аватара пользователя
Shamrel
beginner
beginner
Сообщения: 38
Зарегистрирован: 02 мар 2017, 12:15
Версия LabVIEW: 2015

Re: Асинхронный вызов VI

Сообщение Shamrel »

dadreamer писал(а):
Shamrel писал(а):В этом случае, предложенный мною способ не хуже
Не хуже. Его можно чуть упростить с помощью "Wait On Asynchronous Call". Ну, и у вас анализируется FP.State = Closed, но из-за чего ошибка произошла... :dntknw: Если уж совсем придираться.
Тогда как-то так:
scan_ref2.png
scan_ref2.png (11.59 КБ) 10866 просмотров
Но все равно вызывается в цикле.
dadreamer писал(а): В одной Event-структуре можно будет и обрабатывать UI, и обрабатывать события из параллельно работающих саб-ВИ. Тип эвента можно задать как String, тогда в Саб-ВИ можно генерировать строку в формате "Ссылка (Ref, I32): Само событие (старт/стоп)". По Ref'у можно отследить, какой потомок в какое состояние перешёл. Минимум затрат от разработчика.
А вот над этим подумаю. Спасибо.
Ответить

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