Сообщение создано: 25. 05. 2020 [11:23]
|
adsum
Andrew S
Создатель темы
Зарегистрирован(а) с: 03.10.2013
Сообщения: 31
|
Доброго времени суток!
Есть разработанный модуль DAQ. Он выполняет некоторый функционал, после которого нет необходимости в его исполнении. Причём факт завершения задачи определяется только внутри самого модуля.
Вызов метода close() из самого себя приводит к исключению (что абсолютно логично, т.к. в taskDestroy есть вызов pthread_join). Если просто выйти из цикла, то нить конечно завершается, но из массива задач mTasks запись не удаляется, и флаг runSt не снимается (ну последнее решается, но хочется единообразно).
Пока вижу решение при котором DAQ модуль по завершению работы устанавливает специальный флаг. Разрабатывается дополнительный модуль, в котором модуль DAQ, который должен самозавершиться, регистрируется при запуске. Дополнительный модуль отслеживает факт установки флага для зарегистрированных модулей и даёт команду на остановку DAQ модуля.
Но выглядит это как "костыли". Может есть какое-то нормальное решение этой задачи?
|
Сообщение создано: 25. 05. 2020 [18:26]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
"adsum" wrote:
... Может есть какое-то нормальное решение этой задачи?
Такие вещи реализуються внутри OpenSCADA отдельной процедурой контроллера останова, которая, по условию, останавливает объект контроллера или выгружает модуль через интерфейс управления.
Можно конечно такое встроить прямо в модуль, проверкой условия и останова в сервисной задаче, смотрим виртуальную функцию TModule::perSYSCall().
Learn, learn and learn better than work, work and work.
|
Сообщение создано: 25. 05. 2020 [19:17]
|
adsum
Andrew S
Создатель темы
Зарегистрирован(а) с: 03.10.2013
Сообщения: 31
|
Я пробовал установить флаг runSt в 0 через запрос "set" в cntrCmd. из самой процедуры контроллера. Возможно неправильно формировал запрос, но флаг не сбрасывался.
XMLNode req("set");
req.setAttr("path",cntr.nodePath(0,true)+"/%2fcntr%2fst%2frunSt")->setText("0");
SYS->cntrCmd(&req);
В итоге я решил через класс, наследник TTypeDAQ. В нём создаю дополнительный поток, который проверяет массив со ссылками на объекты контроллеров, которые добавили себя в список, как заявка на завершение. Наверно правильней передавать путь, но я пошёл по пути упрощения и передаю ссылку на объект. Всё отлично работает.
Спасибо. Сейчас посмотрю perSYSCall, что-то я на неё не обратил внимания.
|