TGB (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 13 След.
[ Закрыто] Ищу спеца по ЛуаКвик, для долгосрочного сотрудничества по созданию робота и его доработкам или для консультаций и наставничества.
 
Я поддерживаю поддержку QUIK в стремлении навести порядок на форуме. Здесь не подворотня. «Стычки» между пользователями, конечно, допустимы (в профессиональных рамках), но без перехода на личности. Как мне представляется, «грязный» спам, не имеющий отношение к обсуждаемой теме, поддержка может удалять исходя из своих представлений без объяснения своих мотивов. Миндальничать, наверное, не надо.
Кривые шибки в QLua
 
Цитата
Anton написал:
нет квика под рукой, посмотрите плиз, вот так воспроизведется?

Да
Кривые шибки в QLua
 
Цитата
Daniil Pozdnyakov написал:
спасибо за Ваш комментарий, он будет учтён при разборе.

Тест, описанный в комментарии (10.09.2021) https://forum.quik.ru/messages/forum10/message57872/topic5823/#message57872  упростился (строка с проблемным кодом помечена символом ###):
Код
local for_OnParam = 2 -- Множитель 
local N_OnParam = 0
----
function OnParam(p1, p2)
    for i = 1, for_OnParam do 
      N_OnParam = N_OnParam + 1                                                                              
   end
end
---
--------
IsRun = true
function main()
    local J
    local OnParam_begin   
    -------------------
    while IsRun do 
     ------
     do
        OnParam_begin = N_OnParam   
             J = 100000000   
             while ( J > 0  )   do   J = J - 1  end      -- ### Проблема здесь.   "Чистый" байт-код, но в QLua 5.3 здесь переключаются потоки (! в 5.4 этого нет)---- 
--         for i = 1, 100000000 do  end        --  Это в QLua 5.3 работает нормально  ---

        if N_OnParam ~= OnParam_begin then   --  Счетчик N_OnParam может исмениться только в OnParam  
                message ( ' Переключение колбека и потока main:  N_OnParam - OnParam_begin = ' .. tostring(N_OnParam - OnParam_begin))
            end      
   end
   -----
       sleep(10)  
  end
  ------------------
end   
   
function OnStop()
     IsRun = false
    return 10000   
end
Кривые шибки в QLua
 
Цитата
Anton написал:
Соответственно причина явно не в этом.
 Согласен.  luaL_setfuncs не применима к функциям Lua, а только к С-функциям.
---
 Эксперименты показали, что проблема в lua_pcall (нет блокировки доступа к байт-кодам). Либо в этой функции нет синхронизации в QLua 5.3 (что очень сомнительно), либо в ней не корректно указана ссылка на объект синхронизации (он должен быть общим для всех lua_State скрипта).
Кривые шибки в QLua
 
Цитата
Anton написал:
Этот параметр указывает количество upvalues, прицепленных к каждой функции. Их можно и к сишным функциям прицепить. Соответственно причина явно не в этом.
   Вообще, мне (и остальным пользователям QUIK) не интересны причины наблюдаемой ошибки. Нам существенно, чтобы эта ошибка была устранена.
Кривые шибки в QLua
 
Цитата
Daniil Pozdnyakov написал:
Проблема, о которой Вы говорите, на данный момент изучается, и, к сожалению, какую-либо резолюцию, а также сроки решения данной задачи дать не можем.
   Долго изучаете проблему.
 Не точно, но скорее всего, колбеки регистрируются в QLua (а этого можно и не делать - смотрите мои комментарии) с помощью функции: void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) и, наверное, с параметром nup = 0. Параметр nup = 0 означает, что это C - функции и они запускаются без блокировки байт-кодов. Что является ошибкой.
----
 Возможно, я ошибаюсь, и все-таки просьба к поддержке: донести этот комментарий до разработчиков QUIK.
Выскакивает ворнинг "Compare string with number", А его не должно быть, по идее!
 
Цитата
nikolz написал:
если ядро одно,то не сбросится.
Зачем смуту сеете в «неокрепшие» умы  :smile: ?
---
 Даже если ядро одно, то все равно может сброситься. Потоки и при одном ядре переключаются по времени из-за выделения им квантов процессорного времени. Переключение на выполнение потока колбека может случиться сразу после проверки в main: os.time ()  >  Time. И тогда Time может сброситься при выполнении колбека.
Кривые шибки в QLua
 
Цитата
Daniil Pozdnyakov написал:
Ваше письмо получено, проблема изучается. Постараемся в ближайшее время дать ответ.
    Здравствуйте!
    Появилась версия QUIK 9.2.2.11 (с обновлениями).   В этой версии в QLua 5.3 тест, описанный в комментарии (10.09.2021) https://forum.quik.ru/messages/forum10/message57872/topic5823/#message57872  демонстрирует ошибку в запусках колбеков. Эта ошибка может проявляться как случайные сбои в сриптах пользователей в различные моменты времени.  В версии в QLua 5.4 ошибка не проявляется
    У поддержки есть вопросы по тесту?
Расширить список функций обратного вызова
 
1. nikolz зачем при ссылке на мой код процитировали его весь? Он все-таки длинный и достаточно было бы привести несколько строк. У вас что, есть план по объему генерации текстов своих комментариев  :smile: ?
2. Это
Цитата
nikolz написал:
Квант таймера 0.1  мкс.
вы написали не случайно  :smile: ? А если так, то можно предположить, что это разрешение вашего гипотетического таймера, который вы собираетесь создать (готового пока у вас я не вижу ничего) используя
Цитата
nikolz написал:
пул событий на основе  WaitForMultipleObjects.
Разрешение таймера в 0.1 мкс в Windows (только не путайте с возможностью засечки времени в Windows с использованием QueryPerformanceCounter) было бы круто не только для QLua, но и для C. Я, правда, не очень понимаю, зачем такое разрешение нужно в QLua, но ваша заява так впечатляет и претендует на открытие, что мне стало интересно, а вдруг вы Кулибин от программирования  :smile: .
   Вам известно, что интервалы в WaitForMultipleObjects можно задать только в млсек.?  Вообще, расскажите подробно в деталях, что вам известно о WaitForMultipleObjects (возможно, неизвестное мне), позволяющее, по-вашему, мнению, использовать эту функцию для обеспечения разрешения вашего гипотетического таймера в 0.1 мкс. Только не рассказывайте, это на «растопыренных»  пальцах, а приведите нормальное API и к нему нормальный код (лучше, ваш, работающий, или хотя бы, найденный в сети) на каком-нибудь, известном вам языке программирования. Я попытаюсь такой код понять и как то его прокомментировать.
Расширить список функций обратного вызова
 
Цитата
nikolz написал:
Реализовал  это, создав пул событий на основе  WaitForMultipleObjects.
В итоге бесконечный цикл  запускается через заданный в функции ожидания интервал,т е это тайме собаки,либо при срабатывании любого колбека QLUA или любой функции пользователя, для которой описано событие.
При возникновении события запускается соответствующий ему колбек.
Количество событий- любое. Количество колбеков- любое. Все события  контролируются OC.
Примерно так.
И это весь ваш (очень простой  :smile: ) работающий код, который я могу запустить на своем ПК с тем, чтобы проверить, как он замечательно работает?
--
Цитата
nikolz написал:
Все события  контролируются OC.
 Ну, если бы приведенный вами «код» работал бы, то это было бы, конечно, большое достижение, особенно с учетом того, что все исполняемые приложения контролируются ОС  :smile: .
библиотека для sqlite
 
По ссылке https://cloud.mail.ru/public/ts3g/4PJofyayZ   расположены коды для работы из QLua (5.3,  5.4) c базами SQLite.
   !! Файл  sqlite3.dll одинаковый для 5.3 и 5.4.
Простой вариант подключения к пакету:
1) Переслать файлы варианта 5.3, либо 5.4 в папку с info.exe
2) В скрипте подключиться к пакету следующим образом
Код
local WorkingFolder = getWorkingFolder()   
   package.cpath = package.cpath .. ';' .. WorkingFolder .. '\\?3.dll'      -- C - пакеты  ----
sqlite3 = require('lsqlite3');  ------  Подключение пакета работы с sqlite3  -----
---- Далее использовать функции работы с базами:  sqlite3.<Функция работы с базами>

При таком подключении можно использовать коды только либо для Lua 5.3, либо для Lua 5.4.
Сделать автоматический выбор пакетов в зависимости от того как запускается скрипт (Lua 5.3 или Lua 5.4) несложно.
Расширить список функций обратного вызова
 
3.
Цитата
nikolz написал:
Вы может сами добавить сколько хотите функций обратного вызова.
 Вы что, не поняли и то, что в приведенном мною примере демонстрируется возможность создания таймерных событий столько, сколько потребуется?
Расширить список функций обратного вызова
 
1.
Цитата
nikolz написал:
Попробуйте использовать таймеры ожидания (таймеры ядра)Такое решение и проще и лучше. Не надо создавать новые потоки.Квант таймера 0.1  мкс.Программирование гораздо проще, чем ваша скатерть-самобранка.
 Ну. про это я, наверное, знаю.
А вы попробуйте привести здесь свой работающий код и тогда поговорим.

2.  Тот кто соображает, поймет, что выложенный мною модуль обеспечивает возможность запускать пользователю свои функции в отдельном (от основного потока QUIK) потоке.
Расширить список функций обратного вызова
 
Извините не заметил искажения автора цитаты. В предыдущем комментарии цитата Старателя
Расширить список функций обратного вызова
 
Нужно ли переносить функциональность скрипта в основной поток с учетом написанного мною в предыдущем комментарии, а также с учетом цитируемого ниже?
Цитата
TGB написал:
Таблицы обслуживаются только в одном основном потоке. Доступ к данным - тоже только в одном потоке.Так что все ваши "несколько скриптов" дружно встают в очередь, как только им понадобится что-то вывести в таблицу. И включаются в общую конкурсную массу вмести с другими таблицами и графиками.
   Ответ разработчика QUIK (документ «Использование Lua в Рабочем месте QUIK»):
«При использовании событийной модели Lua скрипт выполняется в двух потоках: функции обратного вызова выполняются в основном потоке РМ QUIK, а функция main() в до-полнительном потоке РМ QUIK (подробнее см. п. 1). При этом для предотвращения «подвисаний» РМ QUIK необходимо каким-либо образом оптимизировать сценарии, описан-ные в функциях обратного вызова. Одним из способов такой оптимизации является перенос логики обработки полученных сигналов в функцию main(). Данный подход сводит количество сценариев в функции обратного вызова до одного, а именно добавление в глобальную Lua таблицу (очередь) записи о том, что функция сработала и вернула определённые значения. Таким образом, мы получаем очередь событий, которые необходимо обработать в другом потоке.»
-----
  Если кому интересно, то в моем комментарии https://forum.quik.ru/messages/forum10/message57686/topic6198/#message57686
выложен код реализации модуля обработки событий колбеков и событий таблиц QUIK с использованием очередей.  Там же приведен скрипт-шаблон подключения модуля и при-мер его использования.
 При использовании очередей проблем синхронизации нет вообще. Основной поток выполняет по событиям QUIK только короткие записи параметров колбеков в очереди, которые обрабатываются в потоке main.
Расширить список функций обратного вызова
 
Цитата
Старатель написал:
Цитата TGB  написал: перенос коротких задач пользователя в колбеки делает скрипт пользователя многопоточным, то есть, при этом пользователю нужно следить за тем, нет ли в  его скрипте проблем синхронизации.

 В данной ветке, наоборот, обсуждение, переноса задачи, выполняемой по таймеру, в основной поток, чтобы не заморачиваться синхронизацией:
Цитата _sk_  написал: удобно иметь возможность инициировать какой-то коллбэк из потока main, не надо думать про синхронизацию

 Из выше приведенного я понял, что о синхронизации мною было написано слишком лапидарно и не очень понятно.
Попробую пояснить это более детально.
   Проблемы синхронизации возникают, только в случае, если у двух или более потоков есть общие модифицируемые при обработке данные. Поэтому при обработке колбеков, до тех пор, пока в main есть только цикл со sleep, то синхронизацией можно не озадачиваться. Но как только, после очередного внесения изменений  в скрип, появятся общие для функций колбеков и функций main модифицируемые данные, с синхронизацией следует разбираться. Причем,  проблемы синхронизации возникают не в отдельных потоках, а при их взаимодействии.
   Конечно, можно всю функциональность скрипта перенести в основной (единственный) поток QUIK и не будет никаких проблем с синхронизацией. Надо только следить за тем, чтобы при изменении скрипта не появились общие (для main и основного потокаQUIK) модифицируемые данные.
Отладка QUIK 8.13
 
Цитата
Anton написал:
Как только ядер больше одного, тут же начинают весьма себе блокировать.
  То есть, для вас чем меньше ядер у ПК, тем лучше?
Отладка QUIK 8.13
 
Цитата
Anton написал:
Выделил ключевое. Как только ядер больше одного, тут же начинают весьма себе блокировать.
 То есть. когда вы пользуетесь браузером, у вас QUIK перестает работать?

Цитата
Anton написал:
Устройте его себе сами . Потом расскажете, удобно ли.
 Рассказываю. То что я уже устроил себе, мне удобно.
Отладка QUIK 8.13
 
Цитата
Старатель написал:
TGB , в одном месте вы  пишите , что байт-код не должен прерываться, в другом наоборот. Вас двое что ли?
  Не надо комплиментов насчет того, что я могу заменить двоих :smile: . Нужно все-таки отличать настоящее и будущее. Вы что. не понимаете разницу между настоящим и будущим? Или притворяетесь? В настоящем байт-код в QLua не должен прерываться (так это сейчас "коряво" реализовано), а я пишу о "светлом" будущем, когда длинные участки участки непрерывного байт-кода не должны блокировать друг друга. Когда вы работаете в любой операционной системе на ПК с одним одним ядром ЦП, то при том что ядро одно, выполнение нескольких приложений в этих ОС не блокируют друг друга, а получают свой кванты ЦП. Про это вам известно?
Отладка QUIK 8.13
 
Цитата
Roman Azarov написал:
TGB , добрый день!
Оба пожелания зарегистрированы, мы постараемся их рассмотреть. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожеланий в будущих версиях ПО.
Каких-либо сроков назвать не можем. Как будет результат анализа пожеланий, мы сообщим Вам в данной теме.

Сегодя 23.09.21.
С тех пор прошло более четырех месяцев. Где результат рассмотрения?
   Просьба к поддержке: сообщить результат рассмотрения первого пожелания (изложенного мною, с протестированным вариантом его реализации в виде конкретного кода), устраняющего блокировку потоков длинными участками байт-кода. У вас есть замечания относительно предложенного мною кода?
Я готов дать развернутый комментарий.
----
!!  Второе пожелание факультатив и, наверное, его не стоит реализовывать. Оно не устраняет ошибок в QLua, достаточно сложное в реализации для разработчиков QUIK (и при некорректной реализации может внести ошибки в QLua) и, наверное, не актуально для большинства пользователей QUIK.
Расширить список функций обратного вызова
 
Цитата
_sk_ написал:
Добавить функцию обратного вызова OnTimer(), которая будет вызываться терминалом с некоторой периодичностью

 В данном комментарии выложен модуль работы с таймерными событиями в отдельном потоке и шаблон его использования.
----
API работы с таймерными событиями:
1) Start_Timer()  -  запуск отдельного  потока обработки таймерных событий.
2) <Ключ события> = Set_Timer  (
{<Имя события>, <Интервал в млсек.>, <Функция обработки события>,{<Список парвметров функции>}} )    - запрос таймерного события.
Через <Интервал в млсек.> будет запущена в отдельном потоке <Функция обработки события> со <Списоком парвметров функции>.
3) delete_Timer (<Ключ события>) – удаление при необходимости запрошенного собы-тия.
----
Модуль и две dll (service53.dll и service54.dll) , скачанные по ссылке:
https://cloud.mail.ru/public/i3Y7/kQHBvs7um  необходимо положить в папку хранения info.exe.
---
Модуль OnTimer (для QLua 5.3 и 5.4):
Код
-- Модуль таймерных событий OnTimer ---
    -- Подключение C-пакетов service53, service54: https://cloud.mail.ru/public/i3Y7/kQHBvs7um
local WorkingFolder = getWorkingFolder()   
package.cpath = package.cpath .. ';' .. WorkingFolder .. '\\?.dll' .. ';' .. WorkingFolder .. '\\?53.dll'.. ';' .. WorkingFolder .. '\\?54.dll' .. ';' .. WorkingFolder .. '\\?51.dll'
                            .. ';' .. WorkingFolder .. '\\?3.dll'      -- C - пакеты  ----
if _VERSION == 'Lua 5.3' then   
    require('service53')     -- Подключает библиотеку service.dll, расположенную в корневом каталоге терминала QUIK (там где info.exe)   ----
else
    require('service54')  
end   
local GetMilliseconds, Start_thread  =   service.GetMilliseconds, service.Start_thread

  --- Функции работы с очередями  ---
    local new  =   function  ()
        return  {first  =   1 , last  =   0 }
    end 
    ---
    local push  =   function  (self, v)
        local  last  =  self.last  +  1 
        self[last]  =  v
        self.last  =  last
        return  last
    end 
    ---
    local pop  =   function  (self)
       local  first  =  self.first
       if  first  >  self.last  then   return   nil   end 
       local  v  =  self [first]
       self.first  =  first + 1 
       self[first]  =   nil 
       return  v, first
     end 
--------- Создание очереди ------
 local  Queue_Timer = new()  --- Таймерные события -----
 local  Queue_Timer_Sl = new()  --- Очередь отмены событий ---
-------------------------------------------
    --- Заказ таймерных событий ----
    --- Таймерное событие:  {<Имя события>, <Интервал в млсек.>, <Функция обработки события>,{<Список парвметров функции>}}
    local function Set_Timer  (self)
       if type(self) == 'table' then 
         if #self >= 3 then
             self [2] = self [2] + GetMilliseconds() 
              return push (Queue_Timer, self)
         else
            message ( '!!! Ошибка. Должно быть:  {<Имя события>, <Интервал в млсек.>, <Функция обработки события>,{<Список парвметров функции>}}') 
         end
      else
         message ( '!!! Ошибка (параметр не таблица). Должно быть:  {<Имя события>, <Интервал в млсек.>, <Функция обработки события>,{<Список парвметров функции>}}') 
      end
    end 
   -----
    local function delete_Timer  (kl)
       push (Queue_Timer_Sl, kl)
    end 
    ------
    local function Timer ()
       local ms, first_q 
       while IsRun   do 
            ---  Обработка удалений событий ---
            ms, first_q = pop (Queue_Timer_Sl) 
            while ms  do
             if Queue_Timer [ms] then Queue_Timer [ms] = nil end
            ms, first_q = pop (Queue_Timer_Sl)    
         end
         ---  Чтение очереди заказанных событий[ -----   
          for k, v in next, Queue_Timer do
            if type(k) == 'number' then
                if v [2] <= GetMilliseconds()   then
                   Queue_Timer [k] = nil
                        if v[4] then
                           pcall ( v[3], table.unpack (v[4]))
                  else
                     pcall ( v[3])  -- функция без параметров ---
                  end
               end
            end
              end
         -------------------------------------------------------
            sleep(2)      
       end
    end 
---------------------------------------
    local function Start_Timer ()
     Start_thread (Timer)
    end
  ------
  return {Set_Timer = Set_Timer, delete_Timer = delete_Timer, Start_Timer = Start_Timer }

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

Шаблон использования модуля:
Код
-- Шаблон использования модуля таймерных событий
local OnTi mer = require('OnTimer')  -- Подключение модуля обработки таймерных событий  ---
local Set_Timer = OnTimer.Set_Timer
local delete_Timer = OnTimer.delete_Timer
local Start_Timer = OnTimer.Start_Timer

IsRun = true

    local function call_Timer  (kl)
        message ( 'call_Timer = ' .. kl)
    end 
   
    local function call_Timer1  ()
        message ( 'call_Timer1  () ==============')
    end 

function main()
    Start_Timer()
   local kl
    --- Заказ таймерных событий ----
    --- Таймерное событие:  {<Имя события>, <Интервал в млсек.>, <Функция обработки события>,{<Список парвметров функции>}}
   kl = Set_Timer({'Set_Timer', 100, call_Timer, {100}})
   kl = Set_Timer({'Set_Timer', 1000, call_Timer, {1000}})
   kl = Set_Timer({'Set_Timer', 5000, call_Timer, {5000}})
   kl = Set_Timer({'Set_Timer', 3000, call_Timer1})
--   delete_Timer (kl)
   
    -------------------
    while IsRun do 
   
       ----  Обработка в main остального -----
       kl = Set_Timer({'Set_Timer', 1000, call_Timer, {1000}})
        delete_Timer (kl)
       ----  Конец Обработка в main остального -----
        sleep(500)        
  end
  ------------------
end   
   
function OnStop()
     IsRun = false
    DestroyTable(TableQUIK)
     DestroyTable(TableQUIK1)
    return 10000   --  !!  По истечении этого интервала времени (в млсек.), данного скрипту на завершение работы, функция main() завершается принудительно. 
                                -- При этом возможна потеря системных ресурсов.   ! Если функция не выдает значение, то по умолчанию оно 5000 (5 сек.)
end
Расширить список функций обратного вызова
 
Цитата
Старатель написал:
Кто сказал "нагружать"? Задачи на 0.1-2 мс, без фанатизма.Я даже не понимаю тех, кто в стремлении "разгрузить" основной поток перекидывает простейшие задачи (с временем выполнения менее 2 мс) из колбеков в main (что опять же не бесплатно в плане нагрузки), создавая километровые очереди и забывая об общей производительности.
 С написанным можно бы согласиться, но с учетом следующих моментов:
1) байт-коды основного потока QUIK и пользовательского потока main выполняются последовательно и пока выполняется один, другой ждет;  то есть использование основного потока для выполнения функций пользователя параллелизм  добавляет только при выполнении C-функций;
2) если у пользователя запущено несколько скриптов, то пока основной поток QUIK выполняется в одном из скриптов, он перестает обслуживать другие скрипты пользователя (в том числе, и созданные им таблицы QUIK);
3) вами выложены в ветке «Кривые ошибки в QLUA» очень эффективные потокобезопасные функции работы с очередями  без синхронизации между основным потоком QUIK и потоком main;
4) перенос коротких задач пользователя в колбеки делает скрипт пользователя многопоточным, то есть, при этом пользователю нужно следить за тем, нет ли в  его скрипте проблем синхронизации.
Расширить список функций обратного вызова
 
Цитата
Nikolay написал:
Да, но зачем нагружать поток терминала, пусть себе в сторонке что-то делается. Тогда можно было бы и нагруженные модули писать. Сейчас же в основном потоке только данные заполнить в общей области видимости, никаких ожиданий и долгих вычислений.
    Справедливое замечание.
 Конечно, между колбеками и функцией main, следует создавать очереди, которые потокобезопасны,  но кто это понимает?
 Большинство из тех, кто заходит на этот сайт, не проффесоналы.
Расширить список функций обратного вызова
 
Цитата
Nikolay написал:
Ну если уж просить, почему бы не попросить еще один поток для своих колбеков. Т.е. реализовать методы регистрации своих функций обратного вызова и отдельный поток для них, чтобы не лезть в основной поток вовсе.
  То есть, это то что, реализовано в OS_Quesha.
У меня есть гипотеза, почему это, до сих пор. не доступно для многих пользователей QUIK, но объявлять это не корректно.
Подскажите как отправлять инфу из QUIK в телеграм?
 
Цитата
Nikolay написал:
Если простыми словами - то это функция объект с своей областью видимости. Что дает возможность создавать разные экземпляры функции с своими переменными.
 А если совсем по-простому, то это модуль, сохраняющий свое состояние (историю своего запуска) между своими запусками на исполнение.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
 
Средства отладки OS_Quesha.
В OS_Quesha средства отладки представлены на трех уровнях:
1) Отладка кода;
2) Отладка приложения на уровне взаимодействия их потоков;
3) Отладка стратегий торговли на фондовом рынке.
  Для отладки кода обеспечены следующие возможности:
1) Ведется потокобезопасный журнал отладки, представляющий собой циклический буфер, реализованный с использованием двух текстовых файлов, между которыми выполняется переключение при заполнении текущего файла. Этот буфер обеспечивает корректную запись сообщений из различных потоков OS_Quesha с высокой частотой. Размер этого буфера задается в глобальных настройках переменной Size_log в кб. События в журнал записываются с точностью до 1 миллисекунды;
2) Печать в скрипте функцией dump_str переменных любых типов, в том числе таблиц QLua со всем их содержимым произвольной вложенности (с существующими метатаблицами);
3) Онлайн печать (при реальной работе) из меню любых глобальных переменных вместе с их содержимым;
4) Использование  в скрипте Pcall_dll, обеспечивающей выполнение функций в защищенном режиме, с централизованной выдачей стека вызова функции в случае возникновения исключений. Дополнительно, если это требуется, многопоточное приложение, в котором возникло такое исключение, останавливается для после-дующего анализа возникшей ошибки;
5) Использование  функции paramete_control для контроля типов параметров,
вызываемых функций;
6) обработка высокочастотных сообщений об ошибках.
 Для отладки приложения на уровне взаимодействия их потоков можно использовать:
1) Настраиваемый, мало влияющий на функционирование приложения, фильтрую-щий вывод сообщений очередей взаимодействия потоков приложения, с привязкой их ко времени, показывающему динамическую картину, в этих очередях;
2) Команду запуска скриптов из меню отладки, обеспечивающую отладку фрагментов разрабатываемых программ в среде OS_Quesha,  в процессе продуктивного функционирования приложения;
3) Команды Останов / Пуск, обеспечивающие «замораживание»/«размораживание» потоков приложения для возможности анализа их состояния.
Отладка стратегий торговли на фондовом рынке обеспечивается:
1) Интерфейсом прогона стратегий торговли на внутренних данных QUIK и истории ко-тировок бумаг, хранимых в базах SQLite;
2) Оперативно сохраняемой историей одноминуток и пятиминуток конкретных, заданных в настройках бумаг, хранимых в базах SQLite;
3) Оперативно обновляемой историей данных по 18 параметрам (конкретных, заданных в настройках бумаг), получаемых по событиям OnParam, с задержкой (относительно этих событий) < 1 млсек. и записываемых в вектора в оперативной памяти;
4) Реализацией виртуальных операций на реальном рынке.
Кривые шибки в QLua
 
Цитата
s_mike@rambler.ru написал:
TGB, прекратите фантазировать.
 Хотелось бы увидеть ваш комментарий (с возможными возражениями), но конкретный, с указанием строк в выложенном мною тесте.
----
Цитата
Daniil Pozdnyakov написал:
Ваше письмо получено, проблема изучается. Постараемся в ближайшее время дать ответ.
 Спасибо. Буду ждать обновления QUIK и после этого запускать свой тест.
Кривые шибки в QLua
 
Где реакция поддержки?
----
  Третий раз (первый комментарий был написан 10.09.2021 07:46:28  https://forum.quik.ru/messages/forum10/message57872/topic5823/#message57872) обращаю внимание поддержки на то, что тест, выложенный 10.09.2021 07:46:28  в данной ветке,  в QUIK (8.13.1.16, 9.1.3.11 и 9.2.1.4 (с последними обновлениями), в QLua 5.3 демонстрирует ошибку в запусках колбеков.  Это подтверждено пользователем Anton (смотрите комментарий 61).
  Если перевести на простой язык, то диагностируется ошибка синхронизации выполнения потока запуска колбеков и потока main скрипта (и это после полутора года эксплуатации новых версий QUIK :!: ). Ошибки синхронизации могут проявляться как случайные сбои в сриптах пользователей в различные моменты времени.
  Что из выше написанного не понятно?
  А если непонятно, то где вопросы?
Кривые шибки в QLua
 
Просьба (повторная) к поддержке: довести содержимое моего комментария: https://forum.quik.ru/messages/forum10/message57872/topic5823/#message57872 до разработчиков QUIK.
  В QUIK 9.2.1.4 (с последними обновлениями) тестовый скрипт, выложенный в упомянутом выше комментарии, демонстрирует, по моему мнению, ошибку в запусках колбеков, в QLua 5.3 ( в  QLua 5.4 эта ошибка не диагностируется, но это не означает, что в 5.4 такой ошибки нет).
Кривые шибки в QLua
 
Цитата
Anton написал:
TGB ,  у меня для вас две новости, как водится:
1) в 5.3 воспроизводится буквально сразу, запущено 4 скрипта и заказаны все параметры по всем инструментам (на боевом);
2) в 5.4 в тех же условинях НЕ ВОСПРОИЗВОДИТСЯ.
 Действительно, в Qlua 5.4 тест ошибку не диагностирует.
---
 Спасибо Антону за его уточнение.
--
А где поддержка?
Кривые шибки в QLua
 
Цитата
Anton написал:
Все такое же, имена поменяйте. Там может вообще темплейт в сорце.
 Имена я способен поменять, но мы же обсуждаем не то что я могу сделать, а как это сделано в текущем QLua.
Цитата
Anton написал:
Это значит, что коллектор начинает агрессивничать и влезать в любую доступную дыру. Где он там дыру в мейне нашел, науке пока неизвестно.
В принципе, если обеспечено четкое разделение между потоками, среды исполнения Lua (то есть, она разделяемый ресурс с корректной синхронизацией доступа к ней) то это эквивалентно однопоточному Lua, в котором ошибки, конечно есть, но их мало.
Кривые шибки в QLua
 
Цитата
Anton написал:
lua_getglobal(s, "OnAllTrade");
  Что то, не  сильно, похоже на детали.  Например, не охватывается случай "OnParam".
А как вы обясните:
Цитата
Anton написал:
в 5.3 воспроизводится буквально сразу, запущено 4 скрипта и заказаны все параметры по всем инструментам (на боевом
----
Цитата
Anton написал:
Это lua_lock() + lua_getglobal() + lua_unlock(), совершенно бессмысленно это проделывать, точно зная, что в скрипте нет такой функции. Дискутировать лень.
 Ну, конечно, вместо lua_getglobal(...)  (кстати, lua_lock() и lua_unlock() выполняется внутри функции lua_getglobal), эквивалентной с точки зрения времени обращения, обращению к глобальной переменной, даже если этой переменной не существует, можно заняться более содержательным алгоритмом регистрации колбеков скриптов (где можно и ошибиться - замечательная возможность).
Кривые шибки в QLua
 
Цитата
Anton написал:
в 5.3 воспроизводится буквально сразу, запущено 4 скрипта и заказаны все параметры по всем инструментам (на боевом);
 Все-таки, воспроизводится.
----
Цитата
Anton написал:
в 5.4 в тех же условинях НЕ ВОСПРОИЗВОДИТСЯ.
 Ну. тогда АРКИ надо объявить, что в версия QLua 5.3 не работоспособна.
---
Цитата
Anton написал:
колбеки так и запускаются, плюс-минус детали.
  Раскажите детали. Мне это было бы интересно.

 
Цитата
Anton написал:
Если не был объявлен, квик его не будет дергать. Очень даже хорошая оптимизация, иначе квик бы на каждое событие разыскивал необъявленные функции во всех скриптах, что несколько затратно, учитывая локи.
  Вы, наверное, знаете, что обращение lua_getglobal (<Основной State в котором запускается колбек>, <Имя колбека>) это эквивалентно обращение в тексте скрипта к переменной скрипта (тоесть. выполняется быстро). Это же обращение к полю таблицы. Или вы думаете, что это не так? Тогда подискутируем.
  А если это так, то о каком "разыскивании по всем скриптам" идет речь, когда происходит обращение к глобальной таблице, определяемой <Основной State в котором запускается колбек>.
  Вообще то, мне было бы интересно пообщаться с главным разработчиком QUIK. Но вы же, похоже не главный?
Кривые шибки в QLua
 
Поддержка понимает, что пока не будут устранены "кривые, мерцающие, редкие" ошибки QLua, на нее будет постоянно валиться вал разнообразных ошибок из  различных функциональностей QLua?
   Если бы я был разработчиком QLua, то в первую очередь занимался бы устранением именно "кривых" ошибок. Это глобальные ошибки, которые могут проявляться у пользователя в любых местах его скриптов, вводя в заблуждения относительно источника ошибок.
Кривые шибки в QLua
 
Я не очень понимаю в чем могут быть проблемы запуска колбеков QLua.
 Вот вариант как это можно сделать просто ( C-API Lua):
Код
   if ( lua_getglobal (<Основной State в котором запускается колбек>, <Имя колбека>) == LUA_TFUNCTION)     // запись и проверка переменной колбека скрипта в стек
   { 
       if ( lua_pcall(<Основной State в котором запускается колбек>, <Количество параметров колбека>, <Список параметров колбека>)  ~= 0 )   // запуск колбека 
      {
          <Обработка ошибки при запуске колбека>
      }
    }
   else    //  в переменной колбека не функция
   {
        <Обработка ошибки пользователя, задавшего в качестве колбека не функцию>
   }


Этот вариант обеспечивает возможность (отсутствующую в существующей версии QLua) замены пользователем функции, вызываемой в качестве колбека, при исполнении скрипта.
Кривые шибки в QLua
 
Просьба к поддержке довести содержимое этого комментария до разработчиков QUIK.
-----
  В версиях QUIK (8.13.1.16  и   9.1.3.11), похоже, есть ошибка, демонстрируемая кодом скрипта, который выложен в комментарии далее.
   Этот скрипт появился в результате анализа редко возникающей «мерцающей» ошибки (похожей на ошибки QLua, описанные Старателем в данной ветке), когда в переменной сразу после присвоения ей значения, это значение на следующем шаге оказывалось искаженным.
   При одновременном запуске трех экземпляров скриптов в QUIKе, подключенного к учебному серверу, в разные моменты времени, но достаточно часто (~ c 10 минутным ин-тервалом) выдается сообщение о том, что параллельно (одновременно) выполняются байт-код потока колбека и байт-код потока main (смотрите текст скрипта). В существующей реализации QLua такого быть не должно. Можно предположить, что в QLua есть ошибка в реализации запуска колбеков.
---
Код скрипта:
Код

  --- Функции работы с очередями (написаны на "чистом" Lua без обращения к C-функциям)  ---
    local new  =   function  ()
        return  {first  =   1 , last  =   0 }
     end 
    ---
    local push  =   function  (self, v)
        local  last  =  self.last  +  1 
        self[last]  =  v
        self.last  =  last
        return  last
     end 
    ---
    local pop  =   function  (self)
       local  first  =  self.first
       if  first  >  self.last  then   return   nil   end 
       local  v  =  self [first]
       self.first  =  first + 1 
       self[first]  =   nil 
       return  v, first
     end 
    ---
    local size  =   function  (self)
        return  self.last  -  self.first  + 1 
     end 
-----
--------- Создание очереди------
local  Queue_QUIK = new()
---------------------------------------

---  Основной поток обработки колбеков "обходит", запушенные на выполнение скрипты, с тем чтобы по событиям запускать их колбеки.
--  При этом должна быть обеспечена корректная синхронизация выполнения байт-кода колбека таким образом, что он не может выполняеться 
--  параллельно с байт-кодом потока main.
----------------------
local for_OnParam = 2 -- Множитель количества записей в очередь ----
local N_OnParam = 0
--- OnParam написана на "чистом" Lua без обращения к C-функциям  ---
function OnParam(p1, p2)
    for i = 1, for_OnParam do 
      N_OnParam = N_OnParam + 1
      -- Зпаись события  ---
      push (Queue_QUIK, {'OnParam', N_OnParam, {p1, p2}})   --  1. здесь создаются таблицы и может быть запущена автоматическая сборка мусора, 
                                                                                            --     которая работает для всей инсталяции Lua и не является потокобезопасной ---                                                                              
   end 
end
   
 ----   Обработка событий QUIK  (написана на "чистом" Lua без обращения к C-функциям) ----      
local function handle_events()   
      ----- ####  Для отладки ---
   local OnParam_begin = N_OnParam   
   local size_Queue_QUIK = size(Queue_QUIK)
   ---------------------------------
   ---  Чтение очереди событий -----
   local ms, first_q = pop (Queue_QUIK) 
      
    while ( ms  )   do        --- Есть события --- 
       -------------------------------
        ---  Чтение очереди событий -----      
        ms, first_q = pop (Queue_QUIK)  --Queue_QUIK: pop()         
   end
    ---   
    for i = 1, 1000 do      end  ---- нагрузка   ####  Отладка ---
   
    if N_OnParam ~= OnParam_begin then   --  Счетчик N_OnParam может иpмениться только в OnParam  
                                                              --  А это означает, что одновременно (параллельно) работают поток main и основной 
                         --  поток обработки колбеков, что недопустимо.
   --- это C-функция, но она вызывается только если  N_OnParam ~= OnParam_begin 
         message ( ' Параллельное выполнение колбека и потока main:  N_OnParam - OnParam_begin = ' .. tostring(N_OnParam - OnParam_begin)
                        .. '    size_Queue_QUIK = ' .. tostring(size_Queue_QUIK) )
    end      
    ----
end      
--------------------------------------------------------------------------------------------------------------------
--------
IsRun = true
function main()
    -------------------
    while IsRun do 
        handle_events()  ----   функция чтения событий OnParam ---
        sleep(2)  
    end
  ------------------
end   
   
function OnStop()
     IsRun = false
    return 10000   
end
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
 
В моем комментарии https://forum.quik.ru/messages/forum10/message57220/topic5823/#message57220
в п.2 было описано предложение по добавлению интерфейса работы с событиями QUIK.
 Ниже выложен код модуля реализации этого предложения на «чистом» Qlua, а также шаблон использования этого модуля. В этом шаблоне демонстрируется схема обработки событий фондового рынка и событий таблиц QUIK.
Для подключения модуля к шаблону его надо сохранить в файле под именем even_handling_module.lua в папку хранения кода запуска QUIK (info.exe).
 Код модуля и шаблона можно использовать свободно. При его распространении желательна ссылка на меня.
 Описание использования модуля приведено в его коде и коде шаблона, описывающего схему обработки событий QUIK.
----
Код модуля:
Код
--[[     TGB      ----   Модуль реализации обработки событий QUIK с использованием очередей событий  фондового рынка и событий таблиц QUIK ---

                                                                               Краткая спецификация модуля.
1. Реализуется схема взаимодействия main с колбеками через две потокобезопасные эффективные очереди, одна из которых обслуживает колбеки 
фондового рынка, а вторая, колбеки событий таблиц QUIK, созданных скриптером;
2. При работе обработке колбеков есть две функции: <функция подписки на события фондового рынка>
 и <функция подписки на события пользовательских таблиц >; в этих функциях скриптер может, в виде списка (в таблице) подписаться на события 
 в соответствии с существующими именами колбеков; реализация подписки сведена к автоматическому созданию (скрытых) от пользователя  
 функций колбеков, записывающих свои параметры с добавлением «от кого параметры» в соответствующие очереди;
3. Для работы с очередями по новой схеме есть две функции чтения соответственно очередям;
 при чтении очередей в считываемой таблице передаются: <имя события>, <время записи в очередь>, <параметры в том виде, как они описаны, в существующих колбеках>.
                При работе по этой схеме, QLua для скриптера становится однопоточным и снимаются многие сложные проблемы. 
----
                              !!  Колбеки OnInit и OnStop обрабатываются как обычно.
-------------------------
--]]
----   Функции работы с очередями (выложенные на форуме Старателем) ------
--- При использовании между потоком колбеков и потоком main  потокобезопасные 
local Queue  =  {
     new  =   function  (self)
        return  setmetatable({first  =   1 , last  =   0 }, {__index  =  self})
     end ,
     push  =   function  (self, v)
        local  last  =  self.last  +  1 
        self[last]  =  v
        self.last  =  last
        return  last
     end ,
     pop  =   function  (self)
        local  first  =  self.first
        if  first  >  self.last  then   return   nil   end 
        local  v  =  self[first]
       self.first  =  first + 1 
       self[first]  =   nil 
        return  v
     end ,
     size  =   function  (self)
        return  self.last  -  self.first  + 1 
     end 
}
--------- Создание очередей-----------
local  Queue_QUIK = Queue:new()
local  Queue_QUIK_tbl = Queue:new()
   ----- Функции чтения очередей -------
local function Queue_evn_QUIK()  return Queue_QUIK: pop()  end 
local function Queue_evn_QUIK_tbl()  return Queue_QUIK_tbl: pop()  end 
----- Функции запроса текущих размеров  очередей -------
local function sizeQueue_evn_QUIK()  return Queue_QUIK: size()  end 
local function sizeQueue_evn_QUIK_tbl()  return Queue_QUIK_tbl: size()  end 
--  Конец Функции работы с очередями  ---------------------------------------

              local function f_nil ()  end 
            ---     Переменные  событий фондового рынка -------
             OnAccountBala nce = f_nil        --- изменение позиции по счету
             OnAccountPosit ion = f_nil          --- изменение позиции по счету
             OnAllTr ade = f_nil                       --- новая обезличенная сделка
             OnClea nUp = f_nil                       --- смена торговой сессии
             OnCl ose = f_nil                            --- закрытие терминала QUIK или выгрузка файла qlua.dll
             OnConnec ted = f_nil                    --- установление связи с сервером QUIK
             OnDepoLi mit = f_nil                    --- изменение бумажного лимита
             OnDepoLimitDel ete = f_nil         --- удаление бумажного лимита
             OnDisconnec ted = f_nil               --- отключение от сервера QUIK
             OnF irm = f_nil                             --- получение описания новой фирмы
             OnFuturesClientHold ing = f_nil        --- изменение позиции по срочному рынку
             OnFuturesLimitCha nge = f_nil         --- изменение ограничений по срочному рынку
             OnFuturesLimitDel ete = f_nil            --- удаление лимита по срочному рынку
--             OnI nit = f_nil                                 --- инициализация функции main
             OnMoneyLi mit = f_nil                  --- изменение денежного лимита
             OnMoneyLimitDel ete = f_nil       --- удаление денежного лимита
             OnNegD eal = f_nil                       --- новая заявка на внебиржевую сделку или изменение параметров существующей заявки на внебиржевую сделку
             OnNegTr ade = f_nil                     --- новая сделка для исполнения или изменение существующей сделки для исполнения
             OnOr der = f_nil                             --- новая заявка или изменение параметров существующей заявки
             OnPa ram = f_nil                           --- изменение текущих параметров 
             OnQu ote = f_nil                            --- изменение стакана котировок
--             OnS top = f_nil                              --- остановка скрипта из диалога управления
             OnStopOr der = f_nil                    --- новая стоп-заявка или изменение параметров существующей стоп-заявки
             OnTr ade = f_nil                            --- новая сделка или изменение параметров существующей сделки
             OnTransRe ply = f_nil                   --- ответ на транзакцию
------                     
            local  unsubscribe_tbl =    ---- Функции отписки  ----
          {
               ['OnAccountBalance'] = function ()   OnAccountBala nce = f_nil   end
             , ['OnAccountPosition'] = function ()   OnAccountPosit ion = f_nil   end
             , ['OnAllTrade'] = function ()   OnAllTr ade = f_nil   end
             , ['OnCleanUp'] = function ()   OnClea nUp = f_nil  end
             , ['OnClose'] = function ()   OnCl ose = f_nil  end
             , ['OnConnected'] = function ()   OnConnec ted = f_nil  end
             , ['OnDepoLimit'] = function ()   OnDepoLi mit = f_nil  end
             , ['OnDepoLimitDelete'] = function ()   OnDepoLimitDel ete = f_nil  end
             , ['OnDisconnected'] = function ()   OnDisconnec ted = f_nil  end
             , ['OnFirm'] = function ()   OnF irm = f_nil  end
             , ['OnFuturesClientHolding'] = function ()   OnFuturesClientHold ing = f_nil  end
             , ['OnFuturesLimitChange'] = function ()   OnFuturesLimitCha nge = f_nil  end
             , ['OnFuturesLimitDelete'] = function ()   OnFuturesLimitDel ete = f_nil  end
--             , ['OnInit'] = function ()   OnI nit = f_nil  end
             , ['OnMoneyLimit'] = function ()   OnMoneyLi mit = f_nil  end
             , ['OnMoneyLimitDelete'] = function ()   OnMoneyLimitDel ete = f_nil  end
             , ['OnNegDeal'] = function ()   OnNegD eal = f_nil  end
             , ['OnNegTrade'] = function ()   OnNegTr ade = f_nil  end
             , ['OnOrder'] = function ()   OnOr der = f_nil  end
             , ['OnParam'] = function ()   OnPa ram = f_nil  end
             , ['OnQuote'] = function ()   OnQu ote = f_nil  end
--             , ['OnStop'] = function ()   OnS top = f_nil  end
             , ['OnStopOrder'] = function ()   OnStopOr der = f_nil  end
             , ['OnTrade'] = function ()   OnTr ade = f_nil end
             , ['OnTransReply'] = function ()   OnTransRe ply = f_nil  end
          }
         -----
            local  subscribe_tbl =    ---- Функции подписки  ----
          {
               ['OnAccountBalance'] = function ()   OnAccountBala nce = function (...)  Queue_QUIK: push ({'OnAccountBalance', os.time (), {...}} ) end   end
             , ['OnAccountPosition'] = function ()   OnAccountPosit ion = function (...)  Queue_QUIK: push ({'OnAccountPosition', os.time (), {...}} ) end    end
             , ['OnAllTrade'] = function ()   OnAllTr ade = function (...)  Queue_QUIK: push ({'OnAllTrade', os.time (), {...}} ) end     end
             , ['OnCleanUp'] = function ()   OnClea nUp = function (...)  Queue_QUIK: push ({'OnCleanUp', os.time (), {...}} ) end  end
             , ['OnClose'] = function ()   OnCl ose = function (...)  Queue_QUIK: push ({'OnClose', os.time (), {...}} ) end  end
             , ['OnConnected'] = function ()   OnConnec ted = function (...)  Queue_QUIK: push ({'OnConnected', os.time (), {...}} ) end  end
             , ['OnDepoLimit'] = function ()   OnDepoLi mit = function (...)  Queue_QUIK: push ({'OnDepoLimit', os.time (), {...}} ) end  end
             , ['OnDepoLimitDelete'] = function ()   OnDepoLimitDel ete = function (...)  Queue_QUIK: push ({'OnDepoLimitDelete', os.time (), {...}} ) end  end
             , ['OnDisconnected'] = function ()   OnDisconnec ted = function (...)  Queue_QUIK: push ({'OnDisconnected', os.time (), {...}} ) end  end
             , ['OnFirm'] = function ()   OnF irm = function (...)  Queue_QUIK: push ({'OnFirm', os.time (), {...}} ) end  end
             , ['OnFuturesClientHolding'] = function ()   OnFuturesClientHold ing = function (...)  Queue_QUIK: push ({'OnFuturesClientHolding', os.time (), {...}} ) end  end
             , ['OnFuturesLimitChange'] = function ()   OnFuturesLimitCha nge = function (...)  Queue_QUIK: push ({'OnFuturesLimitChange', os.time (), {...}} ) end  end
             , ['OnFuturesLimitDelete'] = function ()   OnFuturesLimitDel ete = function (...)  Queue_QUIK: push ({'OnFuturesLimitDelete', os.time (), {...}} ) end  end
--             , ['OnInit'] = function ()   OnI nit = function (...)  Queue_QUIK: push ({'OnInit', os.time (), {...}} ) end  end
             , ['OnMoneyLimit'] = function ()   OnMoneyLi mit = function (...)  Queue_QUIK: push ({'OnMoneyLimit', os.time (), {...}} ) end  end
             , ['OnMoneyLimitDelete'] = function ()   OnMoneyLimitDel ete = function (...)  Queue_QUIK: push ({'OnMoneyLimitDelete', os.time (), {...}} ) end  end
             , ['OnNegDeal'] = function ()   OnNegD eal = function (...)  Queue_QUIK: push ({'OnNegDeal', os.time (), {...}} ) end  end
             , ['OnNegTrade'] = function ()   OnNegTr ade = function (...)  Queue_QUIK: push ({'OnNegTrade', os.time (), {...}} ) end  end
             , ['OnOrder'] = function ()   OnOr der = function (...)  Queue_QUIK: push ({'OnAccountBalance', os.time (), {...}} ) end  end
             , ['OnParam'] = function ()   OnPa ram = function (...)  Queue_QUIK: push ({'OnParam', os.time (), {...}} ) end  end
             , ['OnQuote'] = function ()   OnQu ote = function (...)  Queue_QUIK: push ({'OnQuote', os.time (), {...}} ) end  end
--             , ['OnStop'] = function ()   OnS top = function (...)  Queue_QUIK: push ({'OnStop', os.time (), {...}} ) end  end
             , ['OnStopOrder'] = function ()   OnStopOr der = function (...)  Queue_QUIK: push ({'OnStopOrder', os.time (), {...}} ) end  end
             , ['OnTrade'] = function ()   OnTr ade = function (...)  Queue_QUIK: push ({'OnTrade', os.time (), {...}} ) end  end
             , ['OnTransReply'] = function ()   OnTransRe ply = function (...)  Queue_QUIK: push ({'OnTransReply', os.time (), {...}} ) end  end
          }
         -----   
        -- Подписаться на события фондового рынка --         
        ---  Ключи таблицы - имена событий ----
        local function  subscribe (tbl)
         local err ={},  f
            for k, v in next, tbl do
             f = subscribe_tbl [k]
                if f then f() else  err[#err +1] = k  end
            end   
            return err          
        end
      
      -- Отписаться от событий фондового рынка --
        ---  Ключи таблицы - имена событий ----
        local function  unsubscribe (tbl)
         local err ={},  f
            for k, v in next, tbl do
             f = unsubscribe_tbl [k]
                if f then f() else  err[#err +1] = k  end
            end   
            return err       
        end
      
      --- Вывод данных о состоянии подписки на события фондового рынка  ---
       local function  condition_subscribe ()
             local tbl= {}
            ---
              tbl['OnAccountBalance'] = OnAccountBalance ~= f_nil or nil
              tbl['OnAccountPosition'] = OnAccountPosition ~= f_nil or nil
              tbl['OnAllTrade'] = OnAllTrade ~= f_nil or nil 
              tbl['OnCleanUp'] = OnCleanUp  ~= f_nil or nil
              tbl['OnClose'] = OnClose ~= f_nil or nil 
              tbl['OnConnected'] = OnConnected ~= f_nil or nil 
              tbl['OnDepoLimit'] = OnDepoLimit ~= f_nil or nil 
              tbl['OnDepoLimitDelete'] = OnDepoLimitDelete ~= f_nil or nil
              tbl['OnDisconnected'] = OnDisconnected ~= f_nil or nil 
              tbl['OnFirm'] = OnFirm ~= f_nil or nil
              tbl['OnFuturesClientHolding'] = OnFuturesClientHolding ~= f_nil or nil
              tbl['OnFuturesLimitChange'] =  OnFuturesLimitChange ~= f_nil or nil
              tbl['OnFuturesLimitDelete'] =OnFuturesLimitDelete ~= f_nil or nil
--              tbl['OnInit'] = OnInit ~= f_nil or nil 
              tbl['OnMoneyLimit'] = OnMoneyLimit ~= f_nil or nil
              tbl['OnMoneyLimitDelete'] = OnMoneyLimitDelete ~= f_nil or nil
              tbl['OnNegDeal'] = OnNegDeal ~= f_nil or nil
              tbl['OnNegTrade'] = OnNegTrade ~= f_nil or nil
              tbl['OnOrder'] = OnOrder ~= f_nil or nil
              tbl['OnParam'] = OnParam ~= f_nil or nil
              tbl['OnQuote'] = OnQuote ~= f_nil or nil
--              tbl['OnStop'] = OnStop ~= f_nil or nil
              tbl['OnStopOrder'] = OnStopOrder ~= f_nil or nil
              tbl['OnTrade'] = OnTrade ~= f_nil or nil
              tbl['OnTransReply'] = OnTransReply ~= f_nil or nil
            
          return  tbl   
        end
      
        ----------------------------------------------------------------      
            
 ----   Обработка событий QUIK  ----      
 ----   
local tbl_QUIK_fun  --- Для хранения функции обработки событий таблиц QUIK ---
local tbl_fun            --- Для хранения таблицы функции обработки событий фондового рынка ---
local period = 100    -- период счетчика для выдачи сообшений ---
local event_counter  = 0  -- текущее значение циклов "разгребания" очередей событий ---
local event_counter_mess  = 0  -- счетчик для выдачи сообщений --
local event_counter_mess  = 0  -- счетчик для выдачи сообщений --
local read_latency_max  = 0   -- максимальная задержка чтения очередей событий (сек.)--
------------------------------------------------------------------
         
      local tbl_QUIK = {} ---- Общая таблица состояния обработки таблиц QUIK ---
      ---- Функция обаботки колбеков таблиц QUIK ----
      local function callback_tbl_QUIK(...)  --- (NUMBER t_id, NUMBER msg, NUMBER par1, NUMBER par2
          local par ={...}
         par = par[1]
          if tbl_QUIK[par] then  -- Запись в очередь событий таблиц QUIK.  os.time () - дата_время записи ---
              Queue_QUIK_tbl: push ({par, os.time (), {...}} )
          end
      end 
      
      -- Подписка на события таблицы QUIK  ---
      local function  subscribe_tbl_QUIK (t_id, f_t)
            if    tbl_QUIK[t_id]  then return nil end   
          tbl_QUIK_fun = tbl_QUIK_fun or f_t 
          if SetTableNotificationCallback ( t_id,  callback_tbl_QUIK) == 1 then
             tbl_QUIK[t_id] = 1
            return nil 
         else
            message('!!! Ошибка задания колбека для таблицы: ' ..  t_id)
            error('!!! Ошибка задания колбека для таблицы: ' ..  t_id)
            return nil 
         end
        end
         --   Отписка от событий таблицы QUIK ----
        local function  unsubscribe_tbl_QUIK (t_id) -- Отписка от событий таблицы QUIK  ---
          if tbl_QUIK [t_id]   then tbl_QUIK [t_id] = nil  end
         if  next (tbl_QUIK) == nil then  tbl_QUIK_fun = nil  end
        end
      --  Состояние подписки на события таблицы QUIK ----
      local function condition_subscribe_tbl_QUIK ()  --- Состояние подписки на события таблиц QUIK ---
         return tbl_QUIK
      end
      -----------------------------------------------
---  Установить функции обработки событий  ----
local function install_event_handling_functions(tbl_f)
   tbl_fun = tbl_f
   event_counter  = 0  
   event_counter_mess  = 0 
   event_counter_max  = 0 
   read_latency_max  = 0
   --- Подписка на события фондового рынка ---
   --- ! Ключи таблицы - имена событий ---- 
   unsubscribe (unsubscribe_tbl)  ---- Отписаться от всех событий
   subscribe (tbl_f)   ---  Подписка на события всей таблицы tbl_fun (для записей с функциями обработки событий)
end
 
---- Функция обработки всех событий QUIK:  function handle_events(lim)   -----
--  Параметр lim (по умолчанию равен 1000000)  определяет максимальное количестко событий, обрабатаваемых за один вызов функции --
--- Если очереди событий пусты, то функция завершается.
-- Результат (их три):  1) количество обработанных событий; 2) максимальное количество событий за один вызов функции; 
-- 3) максимальная задержка (в сек.) между записью и чтением событий
local function handle_events(lim)   
   lim = lim or 1000000
   local f_ms
   ---  Чтение очередей событий -----
    local ms_tbl = Queue_QUIK_tbl: pop()   -- ms_tbl = {t_id,  os.time (), {NUMBER t_id, NUMBER msg, NUMBER par1, NUMBER par2}}
   local ms = Queue_QUIK: pop()             -- ms_tbl = {<Имя события>, os.time (), {<Параметры события>}}
   local os_time, os_time_d
   ---
    while (ms_tbl or ms  )   do        -- Есть события --- 
       -------------------------------
      os_time = os.time ()
       event_counter  = event_counter  + 1
      event_counter_mess = event_counter_mess + 1
      if event_counter_mess >= period then
         event_counter_mess = 0
         message ( '!! Длительный цикл обработки событий: ' .. event_counter )
      end
       --- Обработка событий таблиц QUIK ---
       if ms_tbl then   
--  message ( tostring(ms_tbl[1]))
          os_time_d = os_time - ms_tbl [2]
          if read_latency_max < os_time_d then read_latency_max = os_time_d  end
          if tbl_QUIK_fun then  tbl_QUIK_fun (unpack (ms_tbl[3]))  end       -- Запуск функции обработки событий таблиц QUIK ---
       end   
     ----------- События  фондового рынка ---
       if type (tbl_fun) == 'table' then 
           if ms then  
            os_time_d = os_time - ms [2] 
               if read_latency_max < os_time_d  then read_latency_max = os_time_d end      
              f_ms = tbl_fun[ms[1]]
               -- message ( tostring(ms[3][2]))
               if f_ms then f_ms (unpack (ms[3])) end  -- Запуск функции обработки событий фондового рынка ---
           end
      end
      if event_counter >= lim then break  end  
        ---  Чтение очередей событий -----      
         ms_tbl = Queue_QUIK_tbl: pop()   -- ms_tbl = {t_id,  os.time (), {NUMBER t_id, NUMBER msg, NUMBER par1, NUMBER par2}}
        ms = Queue_QUIK: pop()       
   end
   
    ---  Ведение счетчиков циклов обработки событий ----
   if event_counter_max < event_counter then
      event_counter_max = event_counter
   end
   event_counter_rt = event_counter
    event_counter  = 0
    event_counter_mess  = 0
   read_latency_max  = 0
   return event_counter_rt, event_counter_max, read_latency_max
end
      
-----------------------------------------------
 return { 
--   Queue = Queue                                                 --- Функции работы с очередями ----
-- , Queue_evn_QUIK = Queue_evn_QUIK                -- Чтение параметров событий рынка ---
-- , Queue_evn_QUIK_tbl = Queue_evn_QUIK_tbl      -- Чтение параметров событий таблиц QUIK  ---
   sizeQueue_evn_QUIK = sizeQueue_evn_QUIK    -- Текущий размер очереди событий рынка ---
 , sizeQueue_evn_QUIK_tbl = sizeQueue_evn_QUIK_tbl   -- Текущий размер очереди событий таблиц QUIK   ---
 , subscribe = subscribe                                       -- Подписаться на события фондового рынка --
 , unsubscribe = unsubscribe                                -- Отписаться от событий фондового рынка --
 , condition_subscribe = condition_subscribe         -- Сотояние подписки на события фондового рынка --
 , subscribe_tbl_QUIK = subscribe_tbl_QUIK          -- Подписаться на события таблиц QUIK --
 , unsubscribe_tbl_QUIK = unsubscribe_tbl_QUIK   -- Отписаться от событий таблиц QUIK --
 , condition_subscribe_tbl_QUIK = condition_subscribe_tbl_QUIK  -- Сотояние подписки на таблицы QUIK  --
 , install_event_handling_functions = install_event_handling_functions  --  Установить функции обработки событий  ----
 , handle_events = handle_events    -- Функция обработки всех событий QUIK  -----
 }  ---
--------------------------------------




----
Код шаблона:

Код
local even_handling_module = require('even_handling_module')  -- Подключение модуля обработки событий QUIK  ---
---
local subscribe = even_handling_module.subscribe
local unsubscribe = even_handling_module.unsubscribe
local condition_subscribe = even_handling_module.condition_subscribe
local subscribe_tbl_QUIK = even_handling_module.subscribe_tbl_QUIK
local unsubscribe_tbl_QUIK = even_handling_module.unsubscribe_tbl_QUIK
local condition_subscribe_tbl_QUIK = even_handling_module.condition_subscribe_tbl_QUIK
local sizeQueue_evn_QUIK = even_handling_module.sizeQueue_evn_QUIK   
local sizeQueue_evn_QUIK_tbl = even_handling_module.sizeQueue_evn_QUIK_tbl
local install_event_handling_functions = even_handling_module.install_event_handling_functions
local handle_events = even_handling_module.handle_events

IsRun = true

function main()
      
      --- Работа с событиями таблиц QUIK -----
      ----- Функция обработки событий таблиц QUIK  -----
      --  FUNCTION (NUMBER t_id, NUMBER msg, NUMBER par1, NUMBER par2)  ---
      --  t_id – идентификатор таблицы;  msg – код сообщения;  par1 и par2 – значения параметров определяются типом сообщения msg  ----
        local function tbl_QUIK_fun (t_id, msg, par1, par2) 
              message ( 'tbl_QUIK_fun (t_id: ' .. t_id)
       end       
      -----
    TableQUIK=AllocTable()  -- Создание таблицы QUIK --
        AddColumn(TableQUIK, 1, "Легенда", true, QTABLE_STRING_TYPE, 6)
        AddColumn(TableQUIK, 2, "Год", true, QTABLE_STRING_TYPE, 6)
        AddColumn(TableQUIK, 3, "Месяц", true, QTABLE_STRING_TYPE, 6)
        AddColumn(TableQUIK, 4, "День", true, QTABLE_STRING_TYPE, 6)
        CreateWindow(TableQUIK)
        for i=1,10 do -- Цикл заполняет ячейки
                 InsertRow(TableQUIK,-1)
                 for j=1,4 do
                          SetCell(TableQUIK, i, j, tostring(i).."-"..tostring(j))
                 end
        end
      
    TableQUIK1=AllocTable()  -- Создание таблицы QUIK --
        AddColumn(TableQUIK1, 1, "Легенда", true, QTABLE_STRING_TYPE, 6)
        AddColumn(TableQUIK1, 2, "Год", true, QTABLE_STRING_TYPE, 6)
        AddColumn(TableQUIK1, 3, "Месяц", true, QTABLE_STRING_TYPE, 6)
        AddColumn(TableQUIK1, 4, "День", true, QTABLE_STRING_TYPE, 6)
        CreateWindow(TableQUIK1)
        for i=1,10 do -- Цикл заполняет ячейки
                 InsertRow(TableQUIK1,-1)
                 for j=1,4 do
                          SetCell(TableQUIK1, i, j, tostring(i).."-"..tostring(j))
                 end
        end
      ---
        subscribe_tbl_QUIK (TableQUIK, tbl_QUIK_fun)  --- Подписка на события TableQUIK
       subscribe_tbl_QUIK (TableQUIK1, tbl_QUIK_fun)   --- Подписка на события TableQUIK1
  --   unsubscribe_tbl_QUIK (TableQUIK)    --- Отдписка от событий TableQUIK1
   --- Конец  Работа с событиями таблиц QUIK  -----
   
   
   ---  Работа с событиями фондового рынка ----
    ---    Функции обработки событий фондового рынка ---
    local function F_OnParam(p1, p2)
 --      message ( 'Тикер: ' .. tostring(p2))
    end
   --  
    local function F_OnAllTrade(t)
       message ( 'F_OnAllTrade: ' )
    end   
   
   local function F_OnConnected(t)
       message ( 'F_OnConnected: ' )
    end   
   
   ---- и т.д  ----
   -------------------------------------------------------------------
    ------  !!!  Для перехода на обработку событий в очередях, в скрипте достаточно к именам функций колбеков добавить префикс 'F_'
   ---  Таблица функций обработки событий фондового рынка  (параметры как в соответствующих колбеках) -----
    local tbl_fun =  
          {    
               ['OnAccountBalance'] = F_OnAccountBalance   --- Имя функции обработки события OnAccountBalance  --
             , ['OnAccountPosition'] = F_OnAccountPosition   -- и т.д.  ---
             , ['OnAllTrade'] = F_OnAllTrade
             , ['OnCleanUp'] = F_OnCleanUp
             , ['OnClose'] = F_OnClose
             , ['OnConnected'] = F_OnConnected
             , ['OnDepoLimit'] = F_OnDepoLimit
             , ['OnDepoLimitDelete'] = F_OnDepoLimitDelete
             , ['OnDisconnected'] = F_OnDisconnected
             , ['OnFirm'] = F_OnFirm
             , ['OnFuturesClientHolding'] = F_OnFuturesClientHolding
             , ['OnFuturesLimitChange'] = F_OnFuturesLimitChange
             , ['OnFuturesLimitDelete'] = F_OnFuturesLimitDelete
--             , ['OnInit'] = F_OnInit
             , ['OnMoneyLimit'] = F_OnMoneyLimit
             , ['OnMoneyLimitDelete'] = F_OnMoneyLimitDelete
             , ['OnNegDeal'] = F_OnNegDeal
             , ['OnNegTrade'] = F_OnNegTrade
             , ['OnOrder'] = F_OnOrder
             , ['OnParam'] = F_OnParam
             , ['OnQuote'] = F_OnQuote
--             , ['OnStop'] = F_OnStop
             , ['OnStopOrder'] = F_OnStopOrder
             , ['OnTrade'] = F_OnTrade
             , ['OnTransReply'] = F_OnTransReply
          }
         
    install_event_handling_functions (tbl_fun)   -- Установка таблицы функций обработки событий фондового рынка --- 
    ----
    for i, v in next, condition_subscribe() do
        message( 'Скрипт подписан на событие фондового рынка ' .. i )
    end
     ---  Работа с событиями фондового рынка ----
    -------------------
    while IsRun do 
        ---- Функция обработки всех событий QUIK:  function handle_events(lim)   -----
        --  Параметр lim (по умолчанию равен 1000000)  определяет максимальное количестко событий, обрабатаваемых за один вызов функции --
        --- Если очереди событий пусты, то функция завершается.
        --  Результат (их три):  1) количество обработанных событий в вызове функции; 2) максимальное количество обработанных событий за один вызов функции; 
        -- 3) максимальная задержка (в сек.) между записью и чтением событий (в вызове функции).
        local event_counter, event_counter_max, read_latency_max = handle_events()  ----   Обработка всех событий QUIK  ----
      if event_counter > 0 then  -- В очередях были события ----
            message ( 'event_counter: ' .. event_counter ..  ';  read_latency_max: ' .. read_latency_max  )
      end   
       ----  Обработка в main остального -----
   
   
       ----  Конец Обработка в main остального -----
        sleep(2)  
  end
  ------------------
end   
   
function OnStop()
     IsRun = false
    DestroyTable(TableQUIK)
     DestroyTable(TableQUIK1)
    return 10000   --  !!  По истечении этого интервала времени (в млсек.), данного скрипту на завершение работы, функция main() завершается принудительно. 
                                -- При этом возможна потеря системных ресурсов.   ! Если функция не выдает значение, то по умолчанию оно 5000 (5 сек.)
end

Робот как источник пассивного дохода?
 
Цитата
Pavel написал:
на счете будет оставаться 500, всё что заработаю планирую выводить.
 Вы знаете долларовых миллиардеров, заработавших свои состояния на внутридневной торговли на бирже?
 Банки, имеющие ресурсы, позволяющие нанимать совешенно продвинутных аналитиков фондового рынка и айтишников, и имеющие возможность создавать дочерние предприятия, занимающие внутридневной торговлей, предпочитают зарабатывать на комиссиях по обслуживанию такой торговли. Вас это не наводит ни на какие размышления?
 Если бы кто то мог гарантированно получать прибыль 15% годовых в долларах, мы бы это увидели.
Поиск инструмента по названию
 
Цитата
Виталий написал:
Все заработало как следует - терминал перестал падать.
  Вы в какой версии Quik работаете?  При выкладывании ошибок надо указывать версию QUIK, в которой эта ошибка возникает.
Кривые шибки в QLua
 
Цитата
Старатель написал:
и код в сообщении  #24  в частности.
  Ответьте, пожалуйста, есть ли в этом коде вызов стандартных функций? Если есть, то какие и как часто?
Нехватка видеопамяти
 
Цитата
nikolz написал:
пора бы усвоить что халява - она и есть халява.Во-первых, весь квик - это официально бесплатный продукт.
  Это вам так брокеры рассказывают, но при этом в ваших комиссиях брокеру незримо сидит некий процент отчисления за QUIK.
Так что за QUIK пользователь платит и ARQA материально зависит от пользователей.
Кривые шибки в QLua
 
Цитата
s_mike@rambler.ru написал:
и спамить тоже прекращайте.
 
Цитата
s_mike@rambler.ru написал:
и спамить тоже прекращайте.
  Это, конечно, аргумент :smile:  Особенно с учетом того, что вы мне не начальник.
Кривые шибки в QLua
 
Цитата
s_mike@rambler.ru написал:
TGB, прекратите фантазировать.этот код (усложненный) работает в сотнях (может тысячах, я не знаю) копий роботов, из числа выложенных  на сайте и написанных под заказ.
   Вы что, никогда не сталкивались с ситуацией, когда программы использовались сотнями тысячами пользователями и в этих программах потом обнаруживались ошибки?
Кривые шибки в QLua
 
Цитата
s_mike@rambler.ru написал:
этот код (усложненный) работает в сотнях (может тысячах, я не знаю) копий роботов, из числа выложенных  на сайте и написанных под заказ.
 Я же написал, что, похоже, что код потокобезопасный.
 Но если вам все известно, то объясните, что происходит время от времени в коде Старателя?
Кривые шибки в QLua
 
Цитата
Старатель написал:
код в сообщении  #24  в частности.
      Выполненные мною в Lua 5.3 (5.4) тесты атомарности операций вставки/удаления полей в таблицу показали, что эти операции (в условиях реализован-ной многопоточности QLua) все-таки атомарны.  Возможно?, есть ситуации, не охваченные тестированием, когда атомарности может не быть. Если же таких ситуаций нет, то мое утверждение, что выложенный Старателем код Queue (с описанием редко возникающей ошибки) создает потокоопасные очереди, ошибочное.
Кривые шибки в QLua
 
Цитата
Старатель написал:
TGB ,  https://forum.quik.ru/messages/forum10/message57185/topic5823/#message57185 Это ваше сообщение?
Это мое сообщение, но
Цитата
TGB написал:
мы же обсуждаем код Queue_safe
Кривые шибки в QLua
 
Цитата
TGB написал:
TGB  написал:10000 обращений (запись, чтение, удаление) за 500 миллисекунд.Не смотря на то, что сам тест бестолковый, но холостой цикл за 0,5 сек не слишком ли много?
  Опять неточность (мы же обсуждаем код Queue_safe).
В моем обсуждаемом коде Queue_safe во фрагменте тестирования указано:
 --  1.  Этот фрагмент (использование потокобезопасных функций QLua)   (100 000 записей и чтений)  выполняется за ~3560 милисекунд ---
  ................
  --  2. Этот фрагмент (использование Queue_safe)   (100 000 записей и чтений)  выполняется за ~55 милисекунд ---
Кривые шибки в QLua
 
Цитата
Старатель написал:
И не увидел в вашем комментарии каких-то существенных отличий касательно использования метода pop().Больше похоже на спам вашего  OS_...
  Вы в комментарии https://forum.quik.ru/messages/forum10/message57219/topic6198/#message57219
 читали это:
2. Существенная особенность построения очередей в OS_Quesha состоит в том, что они строятся на таблицах, в которых после их создания, нет вставок или удалений их полей (записей). В процессе работы с очередями изменяются только значения существующих полей, обеспечивающих запись/чтения этих очередей. Структура таблиц очередей «заморожена». Это обеспечивает в многопоточном режиме возможность эффективной синхронизации работы с очередями на уровне их полей, а не на глобальном уровне самих очередей.
 Так вот, эта существенная особенность обеспечивает то, что приведенный в комментарии конкретный код модуля Queue_safe создания очередей между колбеками и main является потокобезопасным в существующем QLua, в отличие от выложенного вами Queue, который потокобезопасным не является, о чем я уже писал в этой ветке.
Кривые шибки в QLua
 
Цитата
Старатель написал:
local hour = 0+os.date('%H') выскочила такая ошибка: attempt to perform arithmetic on a nil value
  Ошибка, которую вы обнаружили, замечательна своей локализацией (всего одна строка кода).
---
  Я посмотрел в исходниках Lua 5.3 код функции os.date и то, как она вызывается на исполнение в коде Lua. Этот код не блокирует потоки в текущей версии QLua 5.3 (и это легко проверить).  При этом, os.date, формально, не является C-функцией, так как в внутри ее кода, без блокировки, используется среда исполнения  Lua (ее внутренние функции), формально не гарантирующая корректного параллелизма при ее использовании.  Это же относится к некоторым другим библиотечным функциям Lua, имеющим признак C-функций. В C-функциях можно использовать только C-API Lua. Использование внутренних функции Lua, без блокировки, в коде C-функций является ошибкой.
  В версии Lua 5.3 (а возможно и в 5.4), похоже, есть «дыра» в некоторых ее стандартных функциях, для работы с ними из разных потоков.
  При работе в однопоточном варианте Lua такая «дыра» проявить себя не может. Но, собственно, разработчики Lua не один раз заявляли, что поддерживают однопоточный вариант Lua, а остальное факультатив, с которым надо разбираться тем, кто встраивает Lua в свои решения.
------
   Конечно, можно попытаться анализировать  все коды стандартных функций с используемыми внутренними функциями Lua без блокировки («раскручивая» соответствующие цепочки вызовов внутренних функций Lua) с целью выяснения, вдруг, случайно, какие то, из них, корректны при работе в нескольких потоках. Но по-хорошему, при написании всех кодов модулей библиотечных функции Lua, из ее среды исполнения, должно быть доступно только ее API (обеспечивающее корректность обращения к Lua из разных потоков).
   В принципе, для разработчика QUIK есть простой вариант исправления, в исходниках QLua, стандартных функций с используемыми внутренними функциями Lua без блокировки:
в начале кода таких функций выполняется lua_lock, а при выходах из них (! их может быть несколько) выполняется lua_unlock.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
 
Цитата
Владимир написал:
Мне нет никакого дела до "проблем параллелизма в QLua" - мой скрипт считает, что он один такой работает, и про потоки и прочее знать ничего не знает - для него есть только прерывания от таймера, клавы или мыши.
Думать вы так, конечно, можете, а что же вы иногда жалуетесь на непонятные "падения" вашего скрипта? А может быть и кто то еще получает непонятные ситуации?
Как системщик вы, наверное, должны понимать, что вам (нам) не обеспечена более-менее надежная среда разработки и исполнения скриптов. Вы что против того, чтобы надежность QLua повышалась?  Если нет, то разработчик QUIK должен разбираться, с потоками, синхронизацией и т.д., часто, скрытыми API QUIK, но влияющими работу скриптов. И почему бы, если у кого есть такая возможность, не посодействовать ему, в этом, для нашей пользы?
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 13 След.
Наверх