Запуск скрипта из примера подвешивает терминал Quik

Страницы: 1
RSS
Запуск скрипта из примера подвешивает терминал Quik
 
Вот этот пример из PDF "Использование Lua в Рабочем месте Quik" (пункт 2 "Взаимодействие потоков Lua скрипта") вешает терминал.
Что я делаю не так
 
ни у кого больше не вешает видимо
 
Т.к. в примере присутствует OnAllTrade и у Вас организована подписка на поток сделок, скажем, по многим инструментам, то он будет постоянно блокировать поток для внесения новых данных.
Лучше удалить этот колбек. Либо добавляйте print debug сообщения, для оценки происходящего.
 
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
 
если  комп с несколькими ядрами, то ничего не вешает.
---------------------
Я использую системные события для синхронизации потоков.
-------------------------
Без синхронизации загрузка процессора 33%
с синхронизацией  1-5%.
---------------------
Использование sleep не лучшее решение.
--------------------------
Проще и лучше, если не используете системное событие , использовать флаги.
 
Цитата
Anton Belonogov написал:
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   
В примере уже есть sleep на 3 секунды
куда еще и зачем?
 
относительно sleep.
-------------------------------------
например
вот время реакции колбеков и main.
колбеки вызываются   каждые 2- 5 мкс.
Sleep (1)   даст задержку на 1000 и более мкс.
Вот и посчитайте сколько сигналов изменения цены инструмента Вы пропустите с таким сном.
Код
15,_____(us)=1.8
OnParam(us)=4.2
SBER,kil(us)=1.7 0>0
SBER,ds(us)=3122.7
SBER,set(us)=295.4
14,_____(us)=3506.6
TransReply t(us)=7.2
moneyLimit t(us)=0.5
DepoLimit,SBER,set(us)=0.6
3,_____(us)=153.4
OnParam(us)=46.2
SBER,kil(us)=210.5 1>0
SBER,ds(us)=4.4
SBER,set(us)=179.7
14,_____(us)=603.8
Order t(us)=2.3
Order t(us)=1.4
TransReply t(us)=2.4
Order t(us)=2.0
OnParam(us)=4.5
AFKS,kil(us)=204.9 1>0
AFKS,ds(us)=3187.4
AFKS,set(us)=50.8
14,_____(us)=3676.0
OnParam(us)=4.6
SBER,kil(us)=2.6 0>0
SBER,ds(us)=2.5
SBER,set(us)=508.2
14,_____(us)=1055.1
Order t(us)=2.1
moneyLimit t(us)=0.4
DepoLimit,SBER,set(us)=0.7
3,_____(us)=155.7
TransReply t(us)=1.4
Order t(us)=1.7
TransReply t(us)=4.5
moneyLimit t(us)=0.6
DepoLimit,SBER,set(us)=0.7
3,_____(us)=157.9
DepoLimit,SBER,set(us)=0.5
 
nikolz, Использование sleep - ЛУЧШЕЕ решение! Простое, отлаженное, работающее, эффективное. Не sleep (1), конечно, а sleep (500). Использовать меньшие задержки в скриптах для торговли не вижу ни малейшего смысла. А если нет диалога, то и вообще sleep (1000).
 
Цитата
Владимир написал:
nikolz, Использование sleep - ЛУЧШЕЕ решение! Простое, отлаженное, работающее, эффективное. Не sleep (1), конечно, а sleep (500). Использовать меньшие задержки в скриптах для торговли не вижу ни малейшего смысла. А если нет диалога, то и вообще sleep (1000).
Владимир,
Сможете как-то обосновать Ваше решение лучшего выбора sleep и и величины 500 ms?
------------------------
Раньше Вы писали, что торгуете по 1000 инструментам.
Тогда поясните сколько времени уйдет на обработку  изменений цены инструмента,
если на один инструмент Вы тратите не менее 0.5 секунды сна + время обработки?
------------------------
 
nikolz, А что тут обосновывать? Ещё во времена моей молодости было какое-то исследование, что задержка реакции на действия пользователя свыше 5 секунд вызывает раздражение, свыше 15 секунд - нервные расстройства. С тех пор темп жизни ускорился, процессоры стали круче в тысячи раз, и любая задержка просто недопустима. Полсекунды - та самая граница, до которой юзер задержки не замечает и считает реакцию на свои действия практически мгновенной.

Я не торгую по 1000 инструментам - у меня на это денег нет. Я слежу за 1000 инструментами, а в портфеле у меня болтается несколько десятков (обычно в районе полтинника).

Лапуль, кто Вам сказал, что я "на один инструмент Вы трачу не менее 0.5 секунды сна + время обработки"? Я опрашиваю инструменты раз в секунду, но всю 1000 инструментов сразу. И нет проблем! :wink: Кое-где в этот момент принимаются решения на покупку или продажу, но это обычно лишь несколько десятков или сотен действий в сутки.
 
Цитата
Nikolay написал:
Т.к. в примере присутствует OnAllTrade и у Вас организована подписка на поток сделок, скажем, по многим инструментам, то он будет постоянно блокировать поток для внесения новых данных.
Лучше удалить этот колбек. Либо добавляйте print debug сообщения, для оценки происходящего.
Убрал onAllTrade результат тот же. Может ещё что убрать...
 
Цитата
Anton Belonogov написал:
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   
ProcessingCallbakc содержит sleep на три секунды
 
Konstantin, Коллбек содержит sleep?! Это же самоубийство! :smile:  
 
Цитата
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). А лучше вообще убрать. Я не представляю что необходимо выполнять три секунды на каждый колбек.
 
Цитата
Konstantin написал:
Вот  этот пример  из PDF "Использование Lua в Рабочем месте Quik" (пункт 2 "Взаимодействие потоков Lua скрипта") вешает терминал.
Что я делаю не так
поясню в чем проблема.
В данном примере все колбеки записывают свою информацию в таблицу.
Функция main обрабатывает первую  запись этой таблицы в функции  ProcessingCallbakc
потом удаляет эту запись и обрабатывает следующую
При этом в функции   ProcessingCallbakc есть sleep(3000) т е после обработки каждой записи спим 3 секунды
Выше я привел данные по скорости работы колшбеков
примерно 3 мкс
за время сна 3 секунды в таблицу которую орабатывает main успеет записаться 1000 строк из колбеков
Поэтому и зависает
-------------------  
Это очень плохой пример.
в нем не только плохо сделана работа с колбеками
но и используется удаление строк ирз таблицы что вызывает сдвиг всех строк - это очень медленно так как у Вас в этой таблице уже строк 1000
--------------------
Короче это пример как нельзя писать скрипт.
Какой-то дебил  написал этот примаер.
 
В этом примере куда алгоритмических и смысловых ошибок и заблуждений.
----------------------
Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam?
Если main  
 
В этом примере куда алгоритмических и смысловых ошибок и заблуждений.
----------------------
Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam?
Если main  
 
В этом примере куда алгоритмических и смысловых ошибок и заблуждений.
----------------------
Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam?
Если main  не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.  
 
В этом примере куча алгоритмических и смысловых ошибок и заблуждений.
----------------------
Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam?
Если main  не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.  
 
можно сделать 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    
 
поправил
работает быстро
Код
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
 
Цитата
nikolz написал:
поправил
работает быстро
Код
   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 
  
Да, спасибо, теперь не виснет.
 
Цитата
Konstantin написал:
Цитата
 
Да, спасибо, теперь не виснет.
только в чем причина (разница кода не велика) не понятно
 
Цитата
nikolz написал:
Например, зачем в очередь записывать множество изменений цены инструмента , полученные onParam?
Если main  не успело обработать 999 изменений из 1000, то 999 устарели и важно лишь последнее.
Сам QUIK по такому же принципу работает: если в какой-то момент интерфейс подвиснет на некоторое время, то после оживления покажет вам все изменения цены за то время, пока QUIK был в ауте.


Цитата
nikolz написал:
При этом в функции   ProcessingCallbakc есть sleep(3000) т е после обработки каждой записи спим 3 секунды
Выше я привел данные по скорости работы колшбеков
примерно 3 мкс
за время сна 3 секунды в таблицу которую орабатывает main успеет записаться 1000 строк из колбеков
Поэтому и зависает
Мимо.
Функция ProcessingCallbakc даже не вызывается, потому что в очередь ничего не записывается.


Цитата
Konstantin написал:
в чем причина
Если в основном цикле while is_run do end нет слипа, то он выполняется бесконечно и не прерывается на вызов колбеков. Поэтому счётчик #MAIN_QUEUE не увеличивается, и код даже не заходит в ветку if #MAIN_QUEUE > 0 then
Чтобы колбеки вызывались, нужно добавить в цикл sleep или любую другую C-функцию.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Если в основном цикле  while is_run do end  нет слипа, то он выполняется бесконечно и не прерывается на вызов колбеков. Поэтому счётчик #MAIN_QUEUE не увеличивается, и код даже не заходит в ветку  if #MAIN_QUEUE > 0 then
Чтобы колбеки вызывались, нужно добавить в цикл sleep или любую другую C-функцию.

Добавил seep в main -- не помогло.
 
Цитата
nikolz написал:
В примере уже есть sleep на 3 секунды
куда еще и зачем?
До тех пор пока #MAIN_QUEUE не станет отличной от нуля нет там никакого слипа
Страницы: 1
Читают тему
Наверх