Столкнулся с такой проблемой буквально на последних паре версий 8.8.1 и 8.8.4
В чем проблема: при остановке скрипта квик стал «уходить в себя» (зависать).
Останавливается скрипт банально через OnStop()
Логика там проще некуда:
IsRun = true
OnInit()
CreateDataSource()
end
main()
while IsRun do
getCandlesByIndex()
--доп. запрос данных с индикатора
--и после вычисления
end
end
OnStop()
IsRun = false
end
Все. Структура как по учебнику. Все расчеты внутри main. Никаких допов не подключается, все расчеты сугубо арифметические.
Считают каждую минуту при появлении новых данных по свечам.
После остановки скрипта считать нечего. С рояли он зависает?
Причем весь парадокс в том, что подобное происходит только после продолжительной работы скрипты (где-то от часа и более).
Запущенный и выключенный через 10-15 минут не зависает.
Впечатление будто скрипт в момент остановки не понимает куда сбросить накопившиеся за время работы данные, хотя:
Lua uses automatic memory management that uses garbage collection based on certain algorithms that is in-built in Lua. As a result of automatic memory management, as a developer −
- No need to worry about allocating memory for objects.
- No need to free them when no longer needed except for setting it to nil.
Вопрос не в силе железа или объеме памяти.
Подскажите, кто с таким сталкивался?
UPD:
Переписал OnStop() добавив
return:
function OnStop()
IsRun = false
return 5000
end
Тесты в интервале до 127 минут с прерыванием в разное время проблем не выявило.
Вся структура кода не менялась.
С таким бредом я еще не сталкивался.
Большое спасибо всем неравнодушным.
В ОнСтоп после Фалсе ещё Слип делаю на пару секунд.
А вообще, по хорошему перед Фалсе надо отписаться от данных.
Отписка это CreateDataSource():Close , речь про нее?
Я оттестил два вида источника данных, с графика и через ds. Оба глохнут, хоть и визуально ds шустрее отлагивает.
А Слип, чтобы подождать пока Мейн завершится.
Ну, и спутал, отписка после выхода из цикла
OnStop()
IsRun = false
Sleep(2000)
CreateDataSource():Close
sleep(1000) --это возможно и не надо.
end
Как-то так. Компа нет, подсмотреть негде.
Т.е. по логики там и не нужно ничего вписывать, хотя в примерах чаще всего присутствует дополнительный слип.
В любом языке перед остановкой/завершением программы все ресурсы надо освобождать руками.
А если зависает, то намертво? Или через 5-10 секунд останавливается?
OnStop без разницы где. Это просто внутрянка и она спит до нажатия кнопки «Остановить». Как кнопка нажимается, вызывается OnStop()
Я бы подумал, что процесс main завершается, а далее — вызывается Onstop еще раз и непонятно, что должно произойти. А скрипт завершает уже сам интерпретатор.
Если забить комментом функцию Onstop и скрипт намертво не повиснет, а будет реагировать на кнопку «Остановить», значит трабла в том, что Onstop описана после main()
из того, чему я учился, следовало так:
При нажатии «Остановить» вызывается OnStop(), в ней задается переменная false, далее main начинает новый обход, видит false и завершается.
т.е. даже если я не останавливаю вечный цикл в main, его принудиловкой закрывают.
Где-то в этом моменте зарыта собака.
upd: непрерывная работа скрипта 30 мин — завершение в течении 2 секунд, как и задал.
Положение ONStop() внутри скрипта до или после main значения не имеет, оттестил.
Ну, я предположил, что что-то не то с IsRun из-за того, что закончился main, смутно представляю себе поведение интерпретатора после завершения потока main...
Других идей — нет. Если скрипт зависает — значит зависает while… А почему зависает цикл, особенно, если раньше такого не было — куча вариантов. Вплоть до кривой реализации штатных функций QLUA, типа CreateDataSource()
while IsRun do
сразу идет мелкий слип.sleep(10)
Даже если while и виснет, то делает это через паузу 0,01 сек, чего в целом достаточно чтобы программа сообразила о том, что её завершают.
Поэтому я и заступорился в своих рассуждениях почему так.
Ну дык, я правильно понимаю, что CreateDataSource():Close все полечило?
Вообще ничего не использовал, кроме написания как в мануале return 5000 для ф-ции OnStop.
Все остальное неизменно.
15 мин работы не виснет, 50 мин не виснет. Теперь буду ждать 2 часа и потом стопить.
Жаль, а я, уж, подумал, что все ОК
Мы что видим, то и поем.
так что основной код полный.
Я бы все-таки main поставил в самый низ. Ничего не могу утверждать, но как-то стрёмно видеть описание пользовательских функций ниже основного потока...
Не то что вам нужно, но тоже самое в моем исполнении:
не понял...
Таблица уходит в переменную вот так
ds = CreateDataSource( p_CLASSCODE, p_SECCODE, INTERVAL_M1)
её можно и не инициализировать здесь, т.к. обращение к ней идет в main до запуска бесконечного цикла. Т.е. её роль в ошибке нулевая, т.к. я переписал сегодня код без CreateDataSource()
которая также использует ds_s.
Я и написал, что это не совсем то, что у вас, а как пример другого подхода. В данном случае, событийного.
Имхо, надо не CreateDataSource():Close, а ds_s:Close()
Принципы экстремального программирования.
Разработка с нуля по этапам с отладкой каждого этапа.
Нулевой этап: только OnStop() и main() с минимальным кодом.
Если на этапе 0 сбоя нет, можно наращивать код на следующих этапах.
Однако, посторонние люди разобрались все-таки быстрее :)
===
На какой минуте? Покажи «пальцем».
smart-lab.ru/blog/645552.php#comment11611697
Оказывается, это не равнозначно «Ура, заработало!!!»
Не зависает.
Потому что торговые приказы и их коллбэки обрабатываются через trans2quik.dll
А еще внутри робота (где-нибудь в конце) прописать collectgarbage ().
return прописал, потестил, с ним вроде все ок.
Однако, для больших данных достаточно и var = nil. И уж, если приспичит, тогда уж после этого collectgarbage ().
Но для начала я бы закомментил весь код внутри while и понаблюдал за жизнью голого скрипта и поведением терминала… если все ОК, то раскомментил бы половину кода… и снова прогон… и т.д.))