Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


Временами LTR*_Stop() завершается по таймауту.

Вы не вошли.

 Поиск | Регистрация | Вход 

13.10.2025 22:33:32
#1

Участник
Здесь с 07.10.2025
Сообщений: 7

Временами LTR*_Stop() завершается по таймауту.

Добрый вечер,

Дано:
    1. LTR-EU-16-1 16-местный крейт
    2. Модуль LTR114 с поверкой
    3. Модуль LTR27 c поверкой
    4. Модуль LTR51 с поверкой
    5. Субмодуль H-27I-20
    6. Субмодуль H-27T
    7. Субмодуль H-27U-10
    8. Субмодуль H-51FL

Написали программу, которая работает с модулями выше по аналогии с примерами из документаций
https://www.lcard.ru/download/ltr27api.pdf
https://www.lcard.ru/download/ltr114api.pdf
https://www.lcard.ru/download/ltr51api.pdf

Как и в примерах, каждый модуль проходит по стандартным для него фазам:
1. LTR*_Init()
2. LTR*_Open()
3. Конфигурация модуля и структур
4. LTR*_Start()
5. Собираем и конвертируем данные через LTR*_Recv() и LTR*_ProcessData()
6. LTR*_Stop()
7. LTR*_Close()

Не знаю, важно это или нет, но программа работает со всеми модулями одновременно(в отдельных потоках) и все команды выше также выполняются одновременно в параллели.

Временами при остановке модулей, вызов LTR*_Stop для одного из модулей(вроде как модули всегда разные, закономерности пока не нашел) зависает на 5секунд и возвращает LTR_ERROR_NO_CMD_RESPONSE.

Крейт подключен к ПК с ltrd и нашей программой напрямую через ethernet кабель. Предполагаю, что проблем сетью здесь быть не должно.

Пока по воспроизведениям вижу, что такое может возникнуть в нестандартных или даже некорректных сценариях:
- когда мы доходим до конфигурации модуля(шаг 3), не делаем LTR*_Start(), но делаем LTR*_Stop()
- когда после успешной остановки программы(шаг 6), мы еще раз выполняем  LTR*_Stop()
- видели пару раз такое в моменте, когда был переполнен ltrd буфер для одного(или всех) модуля т.е. зависало при выполнении шага 6.

Обычно, проблема решается повторной отправкой стоп запроса т.е. повторным выполнение функции LTR*_Stop().

Хотелось бы в целом понять, при каких сценариях возможно такое поведение(чтобы быть готовым применить какое то решение) и есть ли еще способы решить проблему, возможно более мягче.

14.10.2025 16:45:33
#2

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,354

Re: Временами LTR*_Stop() завершается по таймауту.

Здравствуйте.

Вы вроде сами приводите порядок вызова функций, поэтому не совсем понятно, как у Вас может вызываться Stop лишний раз или без Start. Корректная работа с модулем подразумевает, что Stop вызывается на успешно выполненный Start один раз, другое использование нештатное и для определенных типов модулей действительно Stop во время не запущенного сбора приводит к такой ошибке.

Если данные не вычитывать и они заполнят весь буфер, то далее из-за отсутствия места станут отбрасываться, если вызвать Stop в этот момент, то так как команды и данные передаются в LTR общим потоком для модуля, то ответ на Stop может быть отброшен из-за отсутствия места в буфера, что может привести к подобной ошибке. Но переполнение это не штатная ситуация, которая при нормальной работе не должна возникать.

Также если используете несколько потоков, то функции, относящиеся к одному модулю (одном описателю) должны вызваться всегда последовательно, т.е. либо из одного потока, либо если из разных, то необходимо гарантировать, что вызываются не одновременно. Если например идет прием и обработка в одном потоке, то нельзя для этого же модуля вызвать просто так Stop или Close из другого потока, нужно вызывать либо из того же потока, либо подавать сигнал для выхода из потока, дождаться его завершения, и только потом уже вызывать Stop из другого.

При корректной последовательности вызовов и штатной работе подобных проблем при вызове Stop возникать не должно. Выполнять вызов последовательности функций правильно целиком в Ваших руках, а переполнение буфера это в общем нештатная ситуация, которая по хорошему требует перезапуск сбора или вообще целиком модуля (Close/Open).

Чтобы проверить, что при корректной последовательности вызовов все нормально работает, можете просто запустить параллельно по примеру на каждый модуль отдельными программами, просто поменяв настройки на нужные.

17.10.2025 13:53:16
#3

Участник
Здесь с 07.10.2025
Сообщений: 7

Re: Временами LTR*_Stop() завершается по таймауту.

Алексей L Card пишет:

Вы вроде сами приводите порядок вызова функций, поэтому не совсем понятно, как у Вас может вызываться Stop лишний раз или без Start.

У нас команды выполняются по нажатию на кнопки, грубо говоря. И бывали случаи, когда кнопки нажимали не по порядку. Видимо, таким образом и словили ошибку, описанную выше.

Возник еще один вопрос, косвенно связанный с данной темой.
Мы хотим делать инициализацию, подключение и конфигурацию модуля(1-3 пункты выше) в одно время(нам это нужно, чтобы гарантировать, что мы ввели корректные параметры и что в целом присутствует связь с модулем), а запуск измерения(4-5пункты) и ,соответственно, остановку в другое. При этом допускается, что разница во времени между этими двумя шагами в теории может достигать 2 и более часов.
Возможно ли таким образом организовать работу(т.е. в два шага выше, при этом с большой задержкой между ними) и не возникнет ли в таком случае каких-нибудь ожидаемых(для Вас) проблем?
Меня, в первую очередь, интересует закрытие соединения между клиентом и ltrd из-за длительной неактивной сессии. Возможно ли такое?
Соединение между крейтом и ltrd "пропинговывается", судя по настройкам ltrd в xml файле, а вот про соединение с клиентом я информации не нашел.
Если разрыв соединения возможен, то есть ли какая-нибудь "холостая" команда в рамках соединения с модулей, которую бы мы могли использовать, чтобы поддерживать активность?
Я думал использовать TCP_KEEPALIVE опцию. Для этого её вроде как надо "включить" для нужного сокета, но ссылку на клиентский сокет внутри л-кард структур я не нашел.

17.10.2025 16:08:43
#4

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,354

Re: Временами LTR*_Stop() завершается по таймауту.

Да, описанный подход возможен и используется (в той же LMS открытие и настройка модулей выполняется при загрузке эксперимента, а запуск сбора/генерации данных уже при нажатии кнопки запуска, которая может быть нажата сильно позже). ltrd не закрывает соединения с клиентом даже если обмена не было долгое время.

Контакты

Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4

Многоканальный телефон:+7 (495) 785-95-25

Письма и запросы: lcard@lcard.ru
Отдел продаж: sale@lcard.ru
Техническая поддержка: support@lcard.ru

Время работы: с 9-00 до 19-00 мск