Запуск скрипта из примера подвешивает терминал Quik
Пользователь
Сообщений: Регистрация: 25.04.2022
26.04.2022 12:38:38
Вот из PDF "Использование Lua в Рабочем месте Quik" (пункт 2 "Взаимодействие потоков Lua скрипта") вешает терминал. Что я делаю не так
Пользователь
Сообщений: Регистрация: 25.04.2022
27.04.2022 12:52:54
ни у кого больше не вешает видимо
Пользователь
Сообщений: Регистрация: 27.01.2017
27.04.2022 13:04:03
Т.к. в примере присутствует OnAllTrade и у Вас организована подписка на поток сделок, скажем, по многим инструментам, то он будет постоянно блокировать поток для внесения новых данных. Лучше удалить этот колбек. Либо добавляйте print debug сообщения, для оценки происходящего.
QUIK clients support
Сообщений: Регистрация: 15.03.2022
27.04.2022 15:21:46
Konstantin, добрый день. Такое поведение связано с особенностями работы Lua-машины: при использовании бесконечных циклов в скрипте необходимо вносить небольшую задержку, иначе возникают зависания. Таким образом, для корректной работы данного скрипта в цикл while в теле функции main нужно добавить функцию sleep:
Код
function main()
while is_run do
if #MAIN_QUEUE > 0 then
ProcessingCallbakc(MAIN_QUEUE[1])
table.sremove(MAIN_QUEUE, 1)
message("Размер очереди " .. tostring(#MAIN_QUEUE))
end
sleep(1)
end
end
Пользователь
Сообщений: Регистрация: 30.01.2015
27.04.2022 20:18:29
если комп с несколькими ядрами, то ничего не вешает. --------------------- Я использую системные события для синхронизации потоков. ------------------------- Без синхронизации загрузка процессора 33% с синхронизацией 1-5%. --------------------- Использование sleep не лучшее решение. -------------------------- Проще и лучше, если не используете системное событие , использовать флаги.
Пользователь
Сообщений: Регистрация: 30.01.2015
27.04.2022 20:21:14
Цитата
Anton Belonogov написал: , добрый день. Такое поведение связано с особенностями работы Lua-машины: при использовании бесконечных циклов в скрипте необходимо вносить небольшую задержку, иначе возникают зависания. Таким образом, для корректной работы данного скрипта в цикл while в теле функции main нужно добавить функцию sleep :
Код
function main ()
while is_run do
if # MAIN_QUEUE > 0 then
ProcessingCallbakc(MAIN_QUEUE[ 1 ])
table.sremove (MAIN_QUEUE, 1 )
message ( "Размер очереди " .. tostring( # MAIN_QUEUE))
end
sleep ( 1 )
end
end
В примере уже есть sleep на 3 секунды куда еще и зачем?
Пользователь
Сообщений: Регистрация: 30.01.2015
27.04.2022 20:33:09
относительно sleep. ------------------------------------- например вот время реакции колбеков и main. колбеки вызываются каждые 2- 5 мкс. Sleep (1) даст задержку на 1000 и более мкс. Вот и посчитайте сколько сигналов изменения цены инструмента Вы пропустите с таким сном.
nikolz, Использование sleep - ЛУЧШЕЕ решение! Простое, отлаженное, работающее, эффективное. Не sleep (1), конечно, а sleep (500). Использовать меньшие задержки в скриптах для торговли не вижу ни малейшего смысла. А если нет диалога, то и вообще sleep (1000).
Пользователь
Сообщений: Регистрация: 30.01.2015
28.04.2022 11:35:54
Цитата
Владимир написал: , Использование sleep - ЛУЧШЕЕ решение! Простое, отлаженное, работающее, эффективное. Не sleep (1), конечно, а sleep (500). Использовать меньшие задержки в скриптах для торговли не вижу ни малейшего смысла. А если нет диалога, то и вообще sleep (1000).
Владимир, Сможете как-то обосновать Ваше решение лучшего выбора sleep и и величины 500 ms? ------------------------ Раньше Вы писали, что торгуете по 1000 инструментам. Тогда поясните сколько времени уйдет на обработку изменений цены инструмента, если на один инструмент Вы тратите не менее 0.5 секунды сна + время обработки? ------------------------
Пользователь
Сообщений: Регистрация: 25.09.2020
28.04.2022 12:54:17
nikolz, А что тут обосновывать? Ещё во времена моей молодости было какое-то исследование, что задержка реакции на действия пользователя свыше 5 секунд вызывает раздражение, свыше 15 секунд - нервные расстройства. С тех пор темп жизни ускорился, процессоры стали круче в тысячи раз, и любая задержка просто недопустима. Полсекунды - та самая граница, до которой юзер задержки не замечает и считает реакцию на свои действия практически мгновенной.
Я не торгую по 1000 инструментам - у меня на это денег нет. Я слежу за 1000 инструментами, а в портфеле у меня болтается несколько десятков (обычно в районе полтинника).
Лапуль, кто Вам сказал, что я "на один инструмент Вы трачу не менее 0.5 секунды сна + время обработки"? Я опрашиваю инструменты раз в секунду, но всю 1000 инструментов сразу. И нет проблем! Кое-где в этот момент принимаются решения на покупку или продажу, но это обычно лишь несколько десятков или сотен действий в сутки.
Пользователь
Сообщений: Регистрация: 25.04.2022
28.04.2022 13:35:00
Цитата
Nikolay написал: Т.к. в примере присутствует OnAllTrade и у Вас организована подписка на поток сделок, скажем, по многим инструментам, то он будет постоянно блокировать поток для внесения новых данных. Лучше удалить этот колбек. Либо добавляйте print debug сообщения, для оценки происходящего.
Убрал onAllTrade результат тот же. Может ещё что убрать...
Пользователь
Сообщений: Регистрация: 25.04.2022
28.04.2022 13:37:14
Цитата
Anton Belonogov написал: , добрый день. Такое поведение связано с особенностями работы Lua-машины: при использовании бесконечных циклов в скрипте необходимо вносить небольшую задержку, иначе возникают зависания. Таким образом, для корректной работы данного скрипта в цикл while в теле функции main нужно добавить функцию sleep :
Код
function main ()
while is_run do
if # MAIN_QUEUE > 0 then
ProcessingCallbakc(MAIN_QUEUE[ 1 ])
table.sremove (MAIN_QUEUE, 1 )
message ( "Размер очереди " .. tostring( # MAIN_QUEUE))
end
sleep ( 1 )
end
end
ProcessingCallbakc содержит sleep на три секунды
Пользователь
Сообщений: Регистрация: 25.09.2020
28.04.2022 14:03:53
Konstantin, Коллбек содержит sleep?! Это же самоубийство!
Пользователь
Сообщений: Регистрация: 27.01.2017
28.04.2022 19:01:38
Цитата
Konstantin написал: Убрал onAllTrade результат тот же. Может ещё что убрать...
Советую последовательно анализировать.
Для начала уберите обработку очереди и просто в каждом колбеке выводите сообщение, что пришел такой колбек. Функция main будет cодержать только sleep(10), например.
Код
function main ()
while is_run do
--if # MAIN_QUEUE > 0 then
-- ProcessingCallbakc(MAIN_QUEUE[ 1 ])
-- table.sremove (MAIN_QUEUE, 1 )
-- message ( "Размер очереди " .. tostring( # MAIN_QUEUE))
--end
sleep ( 10 )
end
end
Потом уже последовательно возвращать в колбеках заполнение очереди. По одному, не во всех сразу. Тогда, анализируя поведение скрипта, найдете причину.
И, главное, измените в функции ProcessingCallbakc sleep(3000) на sleep(10). А лучше вообще убрать. Я не представляю что необходимо выполнять три секунды на каждый колбек.
Пользователь
Сообщений: Регистрация: 30.01.2015
29.04.2022 12:03:01
Цитата
Konstantin написал: Вот из PDF "Использование Lua в Рабочем месте Quik" (пункт 2 "Взаимодействие потоков Lua скрипта") вешает терминал. Что я делаю не так
поясню в чем проблема. В данном примере все колбеки записывают свою информацию в таблицу. Функция main обрабатывает первую запись этой таблицы в функции ProcessingCallbakc потом удаляет эту запись и обрабатывает следующую При этом в функции ProcessingCallbakc есть sleep(3000) т е после обработки каждой записи спим 3 секунды Выше я привел данные по скорости работы колшбеков примерно 3 мкс за время сна 3 секунды в таблицу которую орабатывает main успеет записаться 1000 строк из колбеков Поэтому и зависает ------------------- Это очень плохой пример. в нем не только плохо сделана работа с колбеками но и используется удаление строк ирз таблицы что вызывает сдвиг всех строк - это очень медленно так как у Вас в этой таблице уже строк 1000 -------------------- Короче это пример как нельзя писать скрипт. Какой-то дебил написал этот примаер.
Пользователь
Сообщений: Регистрация: 30.01.2015
29.04.2022 12:10:09
В этом примере куда алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main
Пользователь
Сообщений: Регистрация: 30.01.2015
29.04.2022 12:10:09
В этом примере куда алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main
Пользователь
Сообщений: Регистрация: 30.01.2015
29.04.2022 12:11:17
В этом примере куда алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.
Пользователь
Сообщений: Регистрация: 30.01.2015
29.04.2022 12:11:42
В этом примере куча алгоритмических и смысловых ошибок и заблуждений. ---------------------- Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.
Пользователь
Сообщений: Регистрация: 30.01.2015
29.04.2022 12:50:48
можно сделать main так:
Код
function main()
while is_run do
while #MAIN_QUEUE > 0 then
ProcessingCallbakc(MAIN_QUEUE[1])
table.sremove(MAIN_QUEUE, 1)
end
sleep(100)
end
end
function ProcessingCallbakc(value)
message(string.format("Обработка события %s начата", value.callback))
message(string.format("Обработка события %s завершена", value.callback))
end
Пользователь
Сообщений: Регистрация: 30.01.2015
29.04.2022 13:01:36
поправил работает быстро
Код
function main()
while is_run do
while #MAIN_QUEUE > 0 do
ProcessingCallbakc(MAIN_QUEUE[1])
table.sremove(MAIN_QUEUE, 1)
end
sleep(100)
end
end
function ProcessingCallbakc(value)
message(string.format("Обработка события %s начата", value.callback))
message(string.format("Обработка события %s завершена", value.callback))
end
function main ()
while is_run do
while # MAIN_QUEUE > 0 do
ProcessingCallbakc(MAIN_QUEUE[ 1 ])
table.sremove (MAIN_QUEUE, 1 )
end
sleep ( 100 )
end
end
function ProcessingCallbakc (value)
message ( string.format ( "Обработка события %s начата" , value.callback))
message ( string.format ( "Обработка события %s завершена" , value.callback))
end
только в чем причина (разница кода не велика) не понятно
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
03.05.2022 14:42:56
Цитата
nikolz написал: Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam? Если main не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.
Сам QUIK по такому же принципу работает: если в какой-то момент интерфейс подвиснет на некоторое время, то после оживления покажет вам все изменения цены за то время, пока QUIK был в ауте.
Цитата
nikolz написал: При этом в функции ProcessingCallbakc есть sleep(3000) т е после обработки каждой записи спим 3 секунды Выше я привел данные по скорости работы колшбеков примерно 3 мкс за время сна 3 секунды в таблицу которую орабатывает main успеет записаться 1000 строк из колбеков Поэтому и зависает
Мимо. Функция ProcessingCallbakc даже не вызывается, потому что в очередь ничего не записывается.
Если в основном цикле while is_run do end нет слипа, то он выполняется бесконечно и не прерывается на вызов колбеков. Поэтому счётчик #MAIN_QUEUE не увеличивается, и код даже не заходит в ветку if #MAIN_QUEUE > 0 then Чтобы колбеки вызывались, нужно добавить в цикл sleep или любую другую C-функцию.
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 25.04.2022
06.09.2022 20:03:45
Цитата
Старатель написал: Если в основном цикле while is_run do end нет слипа, то он выполняется бесконечно и не прерывается на вызов колбеков. Поэтому счётчик #MAIN_QUEUE не увеличивается, и код даже не заходит в ветку if #MAIN_QUEUE > 0 then Чтобы колбеки вызывались, нужно добавить в цикл sleep или любую другую C-функцию.
Добавил seep в main -- не помогло.
Пользователь
Сообщений: Регистрация: 03.03.2016
07.09.2022 19:03:34
Цитата
nikolz написал: В примере уже есть sleep на 3 секунды куда еще и зачем?
До тех пор пока #MAIN_QUEUE не станет отличной от нуля нет там никакого слипа