Кривые шибки в QLua

Страницы: Пред. 1 2 3 4 5 6 След.
RSS
Кривые шибки в QLua
 
С точки зрения пользователя, наверное, проще перейти на Lua 5.4 и успокоиться.  Возможно, что ошибка не устраняется или устраняется очень трудоёмко в  рамках того, что было сделано для встраивания Lua 5.3 в терминал. Надо  только используемые внешние библиотеки под версию Lua 5.4 найти.
 
Цитата
Alexey Ivannikov написал:
Информация получена, проблема изучается. Постараемся в ближайшее время дать ответ.
Появилась очередная версия QUIK 9.3.1.11. В этой версии проблема существует.
 
Цитата
TGB написал:
Цитата
Alexey Ivannikov написал:
Информация получена, проблема изучается. Постараемся в ближайшее время дать ответ.
Появилась очередная версия QUIK 9.3.1.11. В этой версии проблема существует.
что-то кажется долго эта версия не протянет - памяти уж больно много жрёт: до 6гб на старте
 
Добрый день,

Мы рекомендуем отказываться от использования Lua 5.3 и переходить на Lua 5.4. Какие-либо доработки в Lua 5.3 не планируются.
 
QUIK 9.3.1.11, Lua 5.4
Ещё парочка "неуловимых" косяков. Обе ошибки были в main. Никаких сторонних библиотек не подключено, только QLua-код.

1.
Код
local Time = tonumber((os.date('%H%M')))
if Time >= 2300 then
Ошибка:
Цитата
attempt to compare number with nil

2.
Код
local Param = getParamEx2('SPBFUT', 'SRZ1', 'STEPPRICE')
tonumber(Param.param_value)  -- вернул nil
Во время ошибки в лог было записано состояние самой таблицы Param:
Код
{result="1", param_type="1", param_image="1,000000", param_value="1.000000"}
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
QUIK 9.3.1.11, Lua 5.4Ещё парочка "неуловимых" косяков. Обе ошибки были в main. Никаких сторонних библиотек не подключено, только QLua-код.
    Итак, в Qlua 5.4 есть «плавающая» ошибка (скорее всего ошибка синхронизации).
  ---  
  «Простой» тест, диагностирующий некорректную обработку колбеков в QLua 5.3, появился у меня в результате анализа «мерцающей» ошибки в скрипте, похожей на ошибки в QLua 5.4, описанные Старателем, когда в переменной сразу после присвоения ей значения, это значение на следующем шаге оказывалось искаженным. Нельзя исключать, что природа ошибок, обнаруженных Старателем и мною одна и та же.
  Притом, что обсуждаемый тест ошибку в QLua 5.4 не показывает на коротком интервале времени, это совсем не значит, что такой ошибки в QLua 5.4 нет. Дело в том, что проявление ошибок синхронизации по времени может сильно зависеть и от того какая версия QLua используется. Я могу ошибаться, но, скорее всего, схемы синхронизации потоков в QLua 5.3 и в QLua 5.4 аналогичны. Поэтому, если бы разработчик QUIK, нашел бы ошибку в QLua 5.3, то он бы, наверное, нашел бы ее и в QLua 5.4. Обсуждаемый тест воспроизводит ошибку (в описанных мною условиях) в QLua 5.3 в интервале 2-3 мин. с локализацией места с точностью одной строки кода.
 
Старатель, добрый день!

Проблема изучается. Постараемся в ближайшее время дать ответ.
 
QUIK 9.4.0.130, Lua 5.4

Код
  function f()
    
    local Hour = tonumber((os.date('%H')))
    return Hour >= 10 and Hour < 22  -- тут возникла ошибка "attempt to compare number with nil"
  end

debug.getlocal() выдала следующие значения локальных переменных на уровне стека:
Цитата
Hour: nil
(temporary): "21"    -- это видимо, значение os.date('%H'), ошибка действительно возникла в 21 ч
(temporary): nil
(temporary): "attempt to compare number with nil"

Для информации: параллельно работали ещё два скрипта. В одном из них в это время за 15 мс (минимальный квант) прошли следующие события: OnParam, OnQuote и 4 х OnOrder
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
local Hour = tonumber((os.date('%H')))
   return Hour >= 10 and Hour < 22  -- тут возникла ошибка "attempt to compare number with nil"
   Эти вопросы, наверное, должна была задать поддержка, но когда она это сделает не-понятно.
 Просьба к Старателю, ответить на следующие вопросы:
1) Как часто это возникает?
2) Где это происходит (в потоке main? В колбеках?)?
  Если это возникает в main, то, как реализован цикл, в котором ошибка проявляется. Это: 1) while; 2) repeat; 3) for  или как-то иначе?  Вопрос «как реализован цикл?» возник, по той причине, что в тесте, представленном мною в этой ветке (https://forum.quik.ru/messages/forum10/message58500/topic5823/#message58500) и демонстрирующем ошибку в QLua 5,3, с высокой частотой, при замене while на for, ошибка  не проявляется.
-----
   Вопрос к разработчику QUIK: где гарантия, что существующая ошибка QLua 5,3  отсутствует в QLua 5,4?  
3) Есть ли возможность создать тест, в котором обнаруженная вами ошибка QLua 5.4 проявляется часто?
 
Os.date есть в конце концов прямой вызов сишной функции и аозможно  win api Неправильно работать оно не может.

Если возникают проблемы, дело не в os.date, а в чем то другом. Испорчен стек вызовов, проблемы синхронизации или что угодно ещё. Грешить на луа не имеет смысла.
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Цитата
s_mike@rambler.ru написал:
Если возникают проблемы, дело не в os.date, а в чем то другом. Испорчен стек вызовов, проблемы синхронизации или что угодно ещё. Грешить на луа не имеет смысла.
Согласен.
Цитата
TGB написал:
в тесте, представленном мною в этой ветке ( https://forum.quik.ru/messages/forum10/message58500/topic5823/#message58500 ) и демонстрирующем ошибку в QLua 5,3, с высокой частотой, при замене while на for, ошибка  не проявляется.
-----    Вопрос к разработчику QUIK: где гарантия, что существующая ошибка QLua 5,3  отсутствует в QLua 5,4?  
 Ответ поддержки, который уже прозвучал ранее: что QLua 5,3 не поддерживается ARQA не "катит".
 
Цитата
TGB написал:
1) Как часто это возникает?
Не часто. Примерно с такой же частотой, как выходят релизы самого квика.

Цитата
TGB написал:
2) Где это происходит (в потоке main? В колбеках?)?
В данном случае ошибка возникла в main. Были ли подобные ошибки в колбеках сложно сказать, поскольку скрипт не останавливается при ошибках в колбеках, и их можно запросто не заметить.

Цитата
TGB написал:
Если это возникает в main, то, как реализован цикл, в котором ошибка проявляется.
while

Цитата
TGB написал:
3) Есть ли возможность создать тест, в котором обнаруженная вами ошибка QLua 5.4 проявляется часто?
Не представляю как это сделать.


Цитата
s_mike@rambler.ru написал:
Если возникают проблемы, дело не в os.date, а в чем то другом.
Что-то мне подсказывает, что nil вернул tonumber, см. значения локальных переменных тут и 2-ю ошибку тут.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
while
    Старатель дал развернутый ответ и за это ему спасибо.
 А где реакция поддержки? Где хотя бы ее спасибо Старателю?  Читает ли ведущий разработчик QUIK сообщения пользователей о ситуациях в QUIK хотя бы по «наводке» поддержки?
-----
  Старатель выложил, найденную им ошибку QLua аж 25.09.2020.
------
  Я выложил тест диагностирующий ошибку QLua 5.3  10.09.2021, который упростил 10.10.2021 до проявления ошибки с частотой в 1-2 минуты и локализации с точностью, что ха-рактерно  :smile: , до оператора while (смотрите https://forum.quik.ru/messages/forum10/message58500/topic5823/#message58500).
  И вот итог  :smile:  7.11.2021использования разработчиком QUIK выложенного мною теста (цитирую поддержку):
«Добрый день,
Мы рекомендуем отказываться от использования Lua 5.3 и переходить на Lua 5.4. Какие-либо доработки в Lua 5.3 не планируются.» (ссылка https://forum.quik.ru/messages/forum10/message59594/topic5823/#message59594)
 Как это можно назвать, не употребляя нецензурных слов?
 Где официальное подтверждение ARQA о том, что QLua 5.3 больше не поддерживается?
 
QUIK 9.3.3.3, Lua 5.4

Код
local function Quotes(queue)
  if type(queue) ~= 'table' then return nil end
  local queue_ = {}
  for i = 1, #queue do
    queue_[tonumber(queue[i].price)] = tonumber(queue[i].quantity)  -- table index is nil
  end
  return queue_
end

  local Stakan = getQuoteLevel2(class_code, sec_code)
  if Stakan then
    local bid = Quotes(Stakan['bid'])
    local offer = Quotes(Stakan['offer'])
  end

В какой-то момент возникает ошибка "table index is nil".
Что-то не так с tonumber?
Надо делать так, как надо. А как не надо - делать не надо.
 
У вас, скорее всего, проблемы синхронизации потоков. В массив queue другой поток уже добавил элемент, но ещё не записал в него значение. Поэтому вы получаете значение nil, которое функция tonumber не может прожевать
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Цитата
s_mike@rambler.ru написал:
В массив queue другой поток уже добавил элемент
В данном конкретном скрипте другой поток массива queue не касается вообще.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Цитата
s_mike@rambler.ru написал:
В массив queue другой поток уже добавил элемент
В данном конкретном скрипте другой поток массива queue не касается вообще.
вот интересно, откуда у вас эта уверенность)
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Вот простой код
Код
function main()
   a = {};--массив
   a[1] = 1;
   a[2] = 3;
   a[3] = 5;
   a[4] = 7;
   a[5] = 9;   
   length = #a;--размер/длина массива
   message("a[1]="..tostring(a[1])..
      "\na[2]="..tostring(a[2])..
      "\na[3]="..tostring(a[3])..
      "\na[4]="..tostring(a[4])..
      "\na[5]="..tostring(a[5])..
      "\na[6]="..tostring(a[6])..
      "\nlength="..tostring(length));
      
end;
Если его запустить, то length = 5.
Если закомментировать a[4]  length = 3.
Если закомментировать a[2] или a[3], то сразу или с какого то раза length = 5.
Я не знаю, почему у меня так, но если у Вас так же, то #a работает не правильно.
Соответственно, Ваш цикл  
Код
for i = 1, #queue do 
   queue_[tonumber(queue[i].price)] = tonumber(queue[i].quantity)  -- table index is nil
end
перебирает и элемент массива который nil
Попробуйте внутри цикла сделать message на каждый queue[i].quantity что бы в этом убедиться(или не убедиться)
 
Цитата
s_mike@rambler.ru написал:
откуда у вас эта уверенность)
Автор скрипта сказал ))

Цитата
Игорь Б написал:
перебирает и элемент массива который nil
Тогда другая была бы ошибка
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
s_mike@rambler.ru написал:
вот интересно, откуда у вас эта уверенность)
 Присоединяюсь.
----
 Дело в том, что стакан обслуживается в потоке отличном от main и может быть ситуация, что при чтении таблиц bid/offer и их проверки на существование они есть, но при обращении к ним они удалены в потоке обслуживания стакана. Но, конечно, желателен разъясняющий комментарий поддержки QLua.
 
Цитата
TGB написал:
при чтении таблиц bid/offer и их проверки на существование они есть, но при обращении к ним они удалены в потоке обслуживания стакана.
Чего?!!  :shock:  От этого ушли лет десять назад ещё при QPILE.
Щас все (или большинство функций) дают вам статическую копию состояния таблицы на момент обращения.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Щас все (или большинство функций) дают вам статическую копию состояния таблицы на момент обращения.
    Вот и пусть это подтвердит поддержка. В любом случае разработчик QLua должен обеспечить возможность корректной работы со стаканом.
 
TGB, уверен, что таблица стакана в данном случае была корректна.
А ошибка похожа на вторую ошибку из сообщения #105.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
TGB написал:
Вот и пусть это подтвердит поддержка.
Вы это сами можете проверить, сохранив стакан в переменную. Состояние этой переменной будет статичным.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
А ошибка похожа на вторую ошибку из сообщения  #105 .
Да. похоже на это.
 
Цитата
Игорь Б написал:
Вот простой код
Вот простой код
Код
function main()
  a = {};--массив
  a[1] = 1;
  a[2] = 3;
  a[3] = 5;
  a[4] = 7;
  a[5] = 9;  
  length = #a;--размер/длина массива
  message("a[1]="..tostring(a[1])..
     "\na[2]="..tostring(a[2])..
     "\na[3]="..tostring(a[3])..
     "\na[4]="..tostring(a[4])..
     "\na[5]="..tostring(a[5])..
     "\na[6]="..tostring(a[6])..
     "\nlength="..tostring(length));
     
end;
Если его запустить, то length = 5.
Если закомментировать a[4]  length = 3.
Если закомментировать a[2] или a[3], то сразу или с какого то раза length = 5.
Все работает правильно.
Чтобы проверить это набираем Ваш пример в Scite -редакторе текста со встроенным отладчиком версия
вот ваш скрипт:
Код
   a = {};--массив
   a[1] = 1;
   a[2] = 3;
   a[3] = 5;
   a[4] = 7;
   a[5] = 9;
   length = #a;--размер/длина массива
   print("a[1]="..tostring(a[1])..
      "\na[2]="..tostring(a[2])..
      "\na[3]="..tostring(a[3])..
      "\na[4]="..tostring(a[4])..
      "\na[5]="..tostring(a[5])..
      "\na[6]="..tostring(a[6])..
      "\nlength="..tostring(length));
Если его запустить, то length = 5.
-----------------
a[1]=1
a[2]=3
a[3]=5
a[4]=7
a[5]=9
a[6]=nil
length=5
>Exit code: 0
>D:/lua54/lua54.exe -e "io.stdout:setvbuf 'no'" "test_.lua"
=====================
Если закомментировать a[4]  length = 3.
a[1]=1
a[2]=3
a[3]=5
a[4]=nil
a[5]=9
a[6]=nil
length=3
>Exit code: 0
==========================
Т е QLUA  не виновата
__________________
В документации на Lua Вы можете прочитать, что
длина массив #a  - не является действительной длиной, если в массиве есть дырки - nil
--------------------------


[CODE][/CODE]
 
Цитата
Старатель написал:
QUIK 9.3.1.11, Lua 5.4
Ещё парочка "неуловимых" косяков. Обе ошибки были в main. Никаких сторонних библиотек не подключено, только QLua-код.

1.  
Код
   local  Time  =  tonumber(( os.date ( '%H%M' )))
 if  Time  >  =   2300   then   
Ошибка:
Цитата
attempt to compare number with nil

2.  
Код
   local  Param  =   getParamEx 2( 'SPBFUT' ,  'SRZ1' ,  'STEPPRICE' )
tonumber(Param.param_value)   -- вернул nil   
Во время ошибки в лог было записано состояние самой таблицы Param:
Код
  {result =  "1" , param_type =  "1" , param_image =  "1,000000" , param_value =  "1.000000" }  
Вопрос к любителям ловли ошибок в QLUA
-----------------
Представим , что в момент вывода функцией main  параметров некоторой таблицы QUIK
происходит вызов терминалом колбека QLUA и изменение этой таблицы.,
------------
Вопросы:
1) что будет выводить функция main в этом случае, то что было до вызова колбека или то, что осталось после вызова.
-------------------------------
2) если будут в параметрах nil,  то это ошибка QLUA, или ошибка писателя main, который использует потоко не безопасные функции в ней?
Например, использовал функцию  getParamEx.
 
Цитата
nikolz написал:
В документации на Lua Вы можете прочитать, чтодлина массив #a  - не является действительной длиной, если в массиве есть дырки - nil
 Иногда вы отвечаете правильно :smile: , но, почти всегда, длинно. Зачем вы цитируете комментарии полностью?
  Я тут с друзьями поспорил на бутылку хорошего коньяка, которую мы, конечно же, вы-пьем вместе.
  Первый друг утверждает, что вы не способны выделить фрагмент текста и потому всегда копируете весь комментарий, на который есть ваша реакция.
  Второй утверждает, что вы интеллектуальный спамер-бот, котрый генериhetn тексты иногда похожие на то, что мог бы выдать посредственный IT- специалист.
  Я же думаю что вы человек, которому платят за то, чтобы вы переполнили базу форума.
       Большая просьба к вам: разрешить наш спор и написать кто из нас прав  :smile: , чтобы мы смогли, наконец, «раздавить» вожделенную бутылку.
 
nikolz,
Ваши результаты совпадают с моими. Но дойдите до третьего варианта, где и появляется ошибка.
Цитата
Если закомментировать a[2] или a[3], то сразу или с какого то раза length = 5.
На луа я пишу в notepad++ и все тестирую в самом квике.
 
Цитата
nikolz написал:
потоко не безопасные функции в ней?
Например, использовал функцию  getParamEx.
И давно getParamEx стала потоконебезопасной?

Цитата
nikolz написал:
Представим , что в момент вывода функцией main  параметров некоторой таблицы QUIK
происходит вызов терминалом колбека QLUA и изменение этой таблицы.,
------------
Вопросы:
1) что будет выводить функция main в этом случае, то что было до вызова колбека или то, что осталось после вызова.
main абсолютно по барабану когда и сколько было вызовов колбеков.
Если состояние таблицы сохранено в переменную,
Код
local Param = getParamEx2(class,  sec,  'TIME')
то даже через час, день, год... её состояние не изменится. main выведет именно то, что сохранили в переменной.

Цитата
nikolz написал:
если будут в параметрах nil,  то это ошибка QLUA, или ошибка писателя main
Если такое случится, то, однозначно, - это зона ответственности разработчика QLUA.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
TGB написал:
Да. похоже на это.
Во всех случаях ошибка возникала в месте явного (через tonumber #105, #108, #114) или неявного (путём математической операции сложения #28) преобразования строки в число.
Надо делать так, как надо. А как не надо - делать не надо.
 
Я думаю, что описанные здесь ошибки (attempt to compare number with nil, tonumber вернул nil и т.п.) есть именно ошибки синхронизации (подобные вещи нередко встречаются и у меня). Места возникновения этих ошибок достаточно очевидны: коллбеки и обращения к таблицам QUIK, т.е. getParamEx, getDepoEx, GetCell и всё такое прочее, причём именно get, в не set - эти ошибки мало интересны. Любая из этих тварей может в любой момент вернуть nil - иногда так, что и сам скрипт вылетит. Надежды на то, что когда-либо хотя бы часть этих ошибок будет исправлена "на стороне Квика" лично у меня нет ни малейшей, так что бороться с ними придётся "подручными средствами". Такими средствами являются:

1. Минимизация использования всего вышеперечисленного: всё, что может сделать сам скрипт, должен делать сам скрипт. В частности, настоятельно рекомендую отказаться от всех "подписных изданий" (стаканов или даже свечей) - это источник головной боли, тормозов и дезинформации. У меня из коллбеков используется только OnTrade и OnStop, каждый из которых в своё время попортил мне немало крови, а OnTrade до сих пор продолжает это делать.

2. Как можно реже обращаться к таблицам Квика. У меня это только "orders", причём обращение к ней через getItem происходит лишь в некоторых экзотических случаях снятия несработавших заявок (вряд ли больше десятка-другого раз за сутки). Кроме того, я обращаюсь (через GetCell и тоже очень редко) к своим таблицам, созданным Квиком, но только к одному из столбцов таблицы по тикерам (невидимому), только для того, чтобы определить "настоящий" ID строки, который не меняется, скажем, при изменении порядка следования строк в таблице после сортировки и только для определения, по какому именно тикеру должно быть вызвано контекстное меню.

3. Проверять на nil во всех таких "опасных" ситуациях - это, по крайней мере, не приведёт к вылету скрипта.

4. Минимизировать время работы коллбеков. Например, мой OnTrade с течением времени оброс всякими проверками до неприличия из-за маразматической и годами не исправляемой ситуации с приходом нескольких прерываний на одно событие, да ещё и вразнобой, а также необходимости учёта "левых" сделок, совершённых в обход скрипта. Похоже, здесь тоже идут какие-то наводки из-за того, что во время обработки коллбека ещё что-то происходит. Планирую максимально облегчить сам OnTrade и перенести основную обработку в прерывание по таймеру, которое фактически находится в потоке main.

5. Очень аккуратно относиться к программированию диалога, средств для организации которого в Lua практически нет. Я толком не понимаю, что там происходит в обработчиках, устанавливаемых по SetTableNotificationCallback, но тут иногда даже не скрипт вылетает, а сам Квик отвисает.

Ну и не обращаться к техподдержке с пожеланиями что-либо исправить: в лучшем случае, останется всё как есть. :smile:  
 
Цитата
Владимир написал:
3. Проверять на nil во всех таких "опасных" ситуациях - это, по крайней мере, не приведёт к вылету скрипта.
 Альтернативный вариант (может быть не единственный): использовать стандартные функции lua pcall или xpcall. Я не буду напрягать публику, как это можно использовать эти функции.

Цитата
Владимир написал:
Ну и не обращаться к техподдержке с пожеланиями что-либо исправить: в лучшем случае, останется всё как есть.
 Вы хотите совершенствоваться в своих программах. Но может и разработчик QUIK тоже хочет улучшать QUIK и QLua. Ну и пусть улучшают.
 
TGB, Мои улучшения касаются именно алгоритмов торговли - о технических проблемах я давно хотел бы забыть, но вот не получается.

Практика показывает, что они и то, и другое только ухудшают. А само обилие версий говорит, что иначе и быть не может.
 
Цитата
Старатель написал:
Код
local Time = tonumber(( os.date ( '%H%M' )))
if Time >= 2300 then
Ошибка:
Цитата
attempt to compare number with nil

Думал такие ошибки возникают только в QUIK 9. Но нет, сегодня в QUIK 8.13 случилась аналогичная ошибка.
QUIK clients support, надо что-то делать. Не хочется все места с tonumber параноидально обкладывать проверкой на nil.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Думал такие ошибки возникают только в QUIK 9. Но нет, сегодня в QUIK 8.13 случилась аналогичная ошибка.QUIK clients support, надо что-то делать. Не хочется все места с tonumber параноидально обкладывать проверкой на nil.

      Этот комментарий пишу, в основном,  для разработчика QUIK.

1. При открытии библиотеки base_funcs (Lua 5.4.1), в которой находится tonumber, все ее функции помечаются как С-функции. Это означает, что в программе Lua они выполняются в скобках:
lua_unlock(L);    Запуск C-функции;    lua_lock(L);
    Такие функции могут выполняться параллельно с исполнением  QLua-кода. Однако любые операции с использованием в них L, должны выполняться в синхронизирующих скобках:
 lua_lock(L);    Выполнение операций в L;     lua_unlock(L);
     При просмотре исходника функции tonumber (с учетом вызываемых в ней функций), я обнаружил, что в этой функции есть как минимум один фрагмент с использованием операций в L без синхронизирующих скобок (мои комментарии помечены в исходнике символами #####):
Код
//   ####  lua_stringtonumber вызывается в tonumber  (luaB_tonumber)
LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
  size_t sz = luaO_str2num(s, s2v(L->top));   //  ##### ? используется L без синхрони-зирующих скобок
  if (sz != 0)
    api_incr_top(L);                                      //  ##### ? используется L без синхронизирующих скобок
  return sz;
}

    Возможно, что-то я упустил, но пусть это проверит разработчик QUIK.
    ----------
2. Есть общая проблема в реализации стандартных функций Lua для многопоточного использования, описанная в моем комментарии: https://forum.quik.ru/messages/forum10/message57243/topic6555/#message57243
-------
3. Существует вариант построения архитектуры встраивания Lua в QUIK, в которой можно использовать однопоточный (нативный) Lua :
1)    вместо регистрации функций обратного вызова, регистрация соответствующих очередей событий (возможно, с теми же именами);  
2)    вместо sleep, использование служебной функции ожидания либо истечения интервала времени (как в sleep), либо появления данных в очередях событий (с выдачей списка непустых очередей);
3) добавление функции чтения очередей событий (их параметров);
4) реализация функций интерфейса c QUIK в виде отдельного пакета dll, подключаемого в Lua.
      Подключение новых версий Lua станет в описанной выше архитектуре рутинной задачей. Исчезнут все проблемы, вызванные текущей многопоточностью QLua.
 
Все что вы пишете в п3 очереди и прочие слипы можно сделать средствами луа без каких либо затруднений
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Цитата
s_mike@rambler.ru написал:
Все что вы пишете в п3 очереди и прочие слипы можно сделать средствами луа без каких либо затруднений
  У меня все это сделано.
Ключевым п.3 является:
Цитата
TGB написал:
Существует вариант построения архитектуры встраивания Lua в QUIK, в которой можно использовать однопоточный (нативный) Lua :
и
Цитата
TGB написал:
Подключение новых версий Lua станет в описанной выше архитектуре рутинной задачей. Исчезнут все проблемы, вызванные текущей многопоточностью QLua.
 
TGB,
вообще-то синхронизация потоков требуется лишь в том случае,
если оба потока будут писать в одну и туже область памяти.
----------------------------
В приведенных Вами рассуждениях о проблеме функции
LUA_API size_t lua_stringtonumber (lua_State *L, const char *s)
нет доказательства, что эта функция изменяет параметры стека луа.
Явно лишь,  что она их читает, т е конфликта эта функция явно не создает.
----------------------
Тот  факт,
что Вы не умеете работать с потоками,
еще не повод давать советы разработчикам
как замедлять работу программ на многоядерных процессорах
используя лишь последовательное их исполнение.
----------------------
Медленно ездить на телеге, не всегда безопаснее , чем быстро на автомобиле.
 
Цитата
TGB написал:
3. Существует вариант построения архитектуры встраивания Lua в QUIK, в которой можно использовать однопоточный (нативный) Lua :
1)    вместо регистрации функций обратного вызова, регистрация соответствующих очередей событий (возможно, с теми же именами);  
2)    вместо sleep, использование служебной функции ожидания либо истечения интервала времени (как в sleep), либо появления данных в очередях событий (с выдачей списка непустых очередей);
3) добавление функции чтения очередей событий (их параметров);
4) реализация функций интерфейса c QUIK в виде отдельного пакета dll, подключаемого в Lua.
      Подключение новых версий Lua станет в описанной выше архитектуре рутинной задачей. Исчезнут все проблемы, вызванные текущей многопоточностью QLua.
Что такое (нативный) Lua ? Это Ваше изобретение?
---------------------------
Один тут "чистый" луа придумал, второй "нативный"
-------------------
Для изобретателей мусора :
================

Обратимся к Wiki

Машинный код (также употребляются термины собственный код, или платформенно-ориентированный код, или родной код, или нативный код — от англ. native code) — система команд (язык) конкретной вычислительной машины (машинный язык), который интерпретируется непосредственно микропроцессором или микропрограммами данной вычислительной машины.

==================

еще раз повторю для особо тупых:

нет ни чистого ни нативного Луа,

каждая команда байт-кода луа - это функция, написанная на языке C.

----------------------

 
Цитата
nikolz написал:
для особо тупых:
 1) вы так и не научились выделять фрагменты текста?
 2) объясняю:  мусорщик Lua не является потокобезопасным, и при его запуске на любом lua_State, он может обрабатывать и все остальные lua_State запущенного скрипта. Таким образом оба потока могут писать в одну и туже область памяти.
-----------------------------------
 
Цитата
nikolz написал:
Что такое (нативный) Lua ?
  Читайте:
Цитата
TGB написал:
однопоточный (нативный) Lua
 
nikolz, для вас тут вопрос давно висит:

Цитата
nikolz написал:
потоко не безопасные функции в ней?
Например, использовал функцию  getParamEx.
И давно getParamEx стала потоконебезопасной?
Если уж умничаете, то умничайте до конца. Либо признайте, что написали глупость.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
TGB написал:
3) Есть ли возможность создать тест, в котором обнаруженная вами ошибка QLua 5.4 проявляется часто?

Добавил в main такой код:
Код
function main()
  xpcall(function()
    ...
    while run do
        ...  --  тут какой-то полезный код
        sleep(1)
        if not tonumber('0') then
          log('tonumber error.')
        end
     end
  end)
end
и в логе обнаружил вот эту запись: 'tonumber error.'
Т.ч. виновник однозначно - tonumber
Но тут надо отметить, что у меня трудится много скриптов в нескольких квиках, а ошибка за неполный день возникла пока только в одном.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
виновник однозначно - tonumber. Но тут надо отметить, что у меня трудится много скриптов в нескольких квиках, а ошибка за неполный день возникла пока только в одном.
    Не факт, что обнаруженная вами сложная ошибка (синхронизации) относится только к tonumber. Существующая реализация разработчиком Lua стандартных C-функций Lua (5.4.1) архитектурно не учитывает многопоточность использования Lua. Для выполнения любых операций в таких функциях с элементами, хранящимися в lua_State, надо было сделать доступным только API-C, но этого не сделано.  Выяснять потокобезопасность каждой такой функции, анализируя ее исходники это, конечно, не решение.
---------
 Когда обсуждаемая ошибка будет устранена разработчиком QUIK неизвестно. Поэтому конкретную проблему с tonumber вы, наверное, могли бы решить следующим образом:
написать в каком-нибуть своем C-пакете собственную, но потокобезопасную функцию tonumber_с, аналогичную tonumber, и в начальном запуске сриптов выполнять перегрузку tonumber = tonumber_с.   Здесь, правда, существует засада: возможно, при неявных преобразованиях строк в число будет вызываться прежняя (потокоопасная) функция.
 
Цитата
TGB написал:
при неявных преобразованиях строк в число будет вызываться прежняя (потокоопасная) функция.
  Например, в выражении:    i = 6 + '100'   ---  (результат число 106)  будет вызвана прежняя функция tonumber.
  -----
  Существующая схема встраивания Lua в QUIK давно (я это наблюдаю с мая 2020г., а началось гораздо раньше) создает много проблем пользователям и разработчикам QLua. Само по себе, использование Lua это, с учетом IT-квалификации большинства пользователей QUIK, хорошее решение, но идея, запуска колбеков в скриптах пользователя в отдельном потоке, плохая. В этой схеме параллелизма выполнения в скрипте пользователя, при использовании только Lua, все равно нет, но есть почти все сложные проблемы многопоточного программирования, создающие нестабильность работы скриптов, даже если пользователь об этом не знает.  Кому это надо?
  В своем комментарии https://forum.quik.ru/messages/forum10/message64087/topic5823/#message64087
в п.3 я написал, как надо бы встраивать Lua в QUIK с тем, чтобы проблем многопоточности скриптов не было. Это, конечно, не отменяет проблем интерфеса скриптов с QUIK.
 
Цитата
TGB написал:
Когда обсуждаемая ошибка будет устранена разработчиком QUIK неизвестно.
Согласен. Поэтому сделал переопределение таким образом:
Код
  local tonumber_ = tonumber
  function tonumber(e, base)
    return tonumber_(e, base) or tonumber_(e, base)
  end
Вероятность возникновения nil не исключает, но значительно снижает.
Раннее уже приходилось делать подобные переопределения для функций getDepoEx, getFuturesLimit и getFuturesHolding.

Цитата
TGB написал:
при неявных преобразованиях строк в число будет вызываться прежняя
Буду постепенно менять на явное преобразование через tonumber, если где в коде встретится неявное.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Вероятность возникновения nil не исключает, но значительно снижает.
 Это хорошее решение, если при возникновение nil не возникает других последствий и не нарушается последующее функционирование скрипта.
 
Цитата
TGB написал:
...
1. При открытии библиотеки base_funcs (Lua 5.4.1), в которой находится tonumber, все ее функции помечаются как С-функции. Это означает, что в программе Lua они выполняются в скобках:
lua_unlock(L);    Запуск C-функции;    lua_lock(L);
    Такие функции могут выполняться параллельно с исполнением  QLua-кода. Однако любые операции с использованием в них L, должны выполняться в синхронизирующих скобках:
 lua_lock(L);    Выполнение операций в L;     lua_unlock(L);
     При просмотре исходника функции tonumber (с учетом вызываемых в ней функций), я обнаружил, что в этой функции есть как минимум один фрагмент с использованием операций в L без синхронизирующих скобок (мои комментарии помечены в исходнике символами #####):
Код
  //    #  #  #  #   lua_stringtonumber вызывается в tonumber  (luaB_tonumber)
LUA_API size_t lua_stringtonumber (lua_State  * L, const char  * s) {
  size_t sz  =  luaO_str2num(s, s2v(L -  > top));   //   #  #  #  #  #  ? используется L без синхрони - зирующих скобок
   if  (sz  !  =   0 )
    api_incr_top(L);                                      //   #  #  #  #  #  ? используется L без синхронизирующих скобок
   return  sz;
}
  

    Возможно, что-то я упустил, но пусть это проверит разработчик QUIK.
...

я немного влезу от скуки, без полного понимания обсуждения, извините, но о каких исходниках идёт речь?
в 5.4.2 Lua есть такой код
Код
#if !defined(lua_lock)
#define lua_lock(L)   ((void) 0)
#define lua_unlock(L)   ((void) 0)
#endif

то есть эти "скобки" ничего не делают на самом деле.

и еще вы пишете что колбеки в текущей реализации не исполняются параллельно main. это действительно как-то так? main где-то приостанавливается? каким образом?
 
Цитата
Павел Bosco написал:
в 5.4.2 Lua есть такой код
Код
#if !defined(lua_lock)
#define lua_lock(L)   ((void) 0)
#define lua_unlock(L)   ((void) 0)
#endif
то есть эти "скобки" ничего не делают на самом деле.
 Этот код  заготовка для использования в нескольких потоках и ничего не делает в однопоточном Lua. Qlua многопоточный из-за выбранной ARQA архитектуры обработки колбеков в отдельном "основном" потоке. Поэтому разработчик QLua заменяет эту заготовку на свои функции синхронизации доступа к коду Lua из нескольких потоков.
 При том, что в запущенном на выполнение скрипте пользователя существует поток main, коды колбеков этого скрипта выполняются в отдельном "основном" потоке. Но все участки кода Lua (за исключением кодов C-функций Lua) используются в режиме разделения, то есть под синхронизацией, при которой только один может исполнять такой код. Таким образом в QLua параллелизм может возникать (если так сложится) только на кодах C-функций Lua (хоть в main, хоть в колбеках).
 
Цитата
TGB написал:
Но все участки кода Lua (за исключением кодов C-функций Lua) используются в режиме разделения, то есть под синхронизацией, при которой только один может исполнять такой код. Таким образом в QLua параллелизм может возникать (если так сложится) только на кодах C-функций Lua (хоть в main, хоть в колбеках).

вы как-то анализировали устройство Qlua? Или это догадки?
Тема мне интересна, есть ли какие-то ссылки почитать? В моем решении есть небольшие болячки. У меня колбэки и main - это c closure, вызовы lua через pcall, при этом я синхронизирую все обращения к main lua_State (к ней обращение во много потоков) через критическую секцию
Болячки выражаются в замедлении квика (отставании времени от сервера), если открыт GUI, а если он минимизирован - всё шустро очень - но так его держать неудобно.
Тоже думал что есть какие-то проблемы с блокировками, но на видимом мне слое "реальности" ничего не нашел.
Страницы: Пред. 1 2 3 4 5 6 След.
Читают тему
Наверх