Anton написал: Вы обнаружили, что на время вызова любой сишной функции (а не только sleep) луа снимает лок, и сделали неправильный вывод, подумав только на sleep. В качестве такой функции может выступить и message, как в примере, и любая встроенная в луа библиотечная функция, и любая функция qlua.
Обкладывать синхронизацией все используемые сишные функции в однопоточном QLua для меня неожиданное решение. Мне, казалось, что с учетом рекомендуемого ARQA способа взаимодействия колбеков c потоком main через очереди, в существующей реализации достаточно было синхронизировать только sleep. Вообще, в однопоточном QLua можно было бы практически полностью отказаться от всякой синхронизации и от модификации исходного Lua. При этом можно бы было сохранить и существующий пользовательский интерфейс обработки колбеков. Для этого можно модифицировать функцию sleep следующим образом. В модифицированной функции (например, с именем sleep_q) ожидается либо истечение интервала времени (как в sleep), либо появление данных в очередях событий скрипта. При наличии или появлении таких событий в этой функции запускаются все, соответствующие событиям, колбеки скрипта и далее работа продолжается как обычно. В этом варианте: 1) внутри Qlua полностью отсутствует синхронизация, а вся синхронизация, связанная с обработкой очередей между основным потоком и потоком main, может быть сосредоточена в sleep_q; 2) заметно разгружается основной поток (он подготавливает очереди событий (это делает и сейчас) и при необходимости выдает лишь сигнал о начале их обработки); 3) для включения Lua в QUIK не требуется модификация исходного Lua, а значит, облегчается подключение новых версий Lua а также повышается надежность среды исполнения скриптов: 4) в целом, обеспечивается простота сопровождения QUIK.
Anton написал: TGB , неправда. Если бы было правдой, в следующем скрипте между сообщениями 'Before loop' и 'After loop' ни одно сообщение 'OnAllTrade' вклиниться не могло
Правда. При выполнении таких тестов (анализ выполнения потоков) необходимо для вывода сообщений вместо message использовать PrintDbgStr. Сделайте такую замену и прогоните ваш тест заново. Для просмотра результатов используйте Dbgview. Я прогонял ваш тест (с предложенной вам заменой). Между сообщениями 'Before loop' и 'After loop' ни одно сообщение 'OnAllTrade' не вклинилось.
В QUIK 8.11 (QLua 5.3.5) обработка колбеков выглядит следующим образом. 1. QLua 5.3.5 однопоточный и тем самым снимаются вопросы по моему тесту управления памятью в многопоточном QLua. 2. В скрипте пользователя могут существовать два потока одновременно: поток main и основной поток, в котором запускаются колбеки скрипта. Причем выполнение любого из перечисленных потоков блокирует выполнение другого. Таким образом предполагается обеспечивать корректность работы двух потоков в однопоточном QLua 5.3.5. Переключение потоков реализовано следующим образом. Колбеки могут запускаться только тогда, когда поток main «висит» в операции sleep(<интервал ожидания>). Пока запущенный колбек выполняется, поток main не может продолжить свою работу, даже если истек его <интервал ожидания>. Если, вдруг, в колбеке используется операция sleep(<интервал ожидания>), то она выполняется точно также, как это описано для потока main. То есть, зависание колбека на операции sleep допускает выполнение потока main, но при этом поток колбека «отвиснет» только тогда, когда поток main попадет на свою операцию sleep. Реализованную схему обработки событий элегантной назвать трудно, но она позволяет сохранить существующий пользовательский интерфейс.
Roman Azarov написал: Anton , Благодарим за дополнительную информацию.
Мне, кажется, что Anton, действительно, сделал большую и качественную работу по улучшению обработки исключений в QLua. Наверное, можно бы было как то использовать и его исходники по обработке исключений, с каким-то реальным вознаграждением. Почему бы нет?
Старатель написал: __gc срабатывает до вызова collectgarbage, возможно при автоматической сборке.
Мне, кажется, что ваше предположение верное. В своем комментарии с программой, внутри нее я специально отметил, что вариант с локальным объявлением gcrunner не работает в QLua 5.3.5 для финализации скрипта. Вообще то, похоже, это баг.
Andrey Bezrukov написал: Для прочих функций мы не гарантируем потокобезопасность.
А для колбеков вы гарантируете их потокобезопасность? Они же выполняются в отдельном потоке, в контексте скрипта пользователя, в котором работает и поток main. А если если гарантируете, то чем?
Старатель написал: Цитата TGB написал:-- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. Вроде, не срабатывает.
Здравствуйте! При этом необходимо, чтобы gcrunner был объявлен локальным: local gcrunner = {}
swerg написал: Я не смотрел вашу программу, однако могу предложить другое объяснение: ваша программа портит память процесса QUIK, после чего он падает. Или подгружаемые вами DLL содержат потоконебезопасный код, из-за которого опять же QUIK падает.Если бы на самом деле управление внутренними хранилищами QUIK было столь потоконебезопасным, то падали бы и обычные скрипты, которые могут нагрузить "автоматческую память" ничуть не хуже.
А как вы объясните, что точно эта же программа в QUIK версиях 8.4... без проблем работает без перезапусков неделями?? Если сомневаетесь, то можете поэкспериментировать. Коды и для версии 8.4.. выложены по ранее указанной мною ссылки.
Цитата
swerg написал: Если бы на самом деле управление внутренними хранилищами QUIK было столь потоконебезопасным, то падали бы и обычные скрипты, которые могут нагрузить "автоматческую память" ничуть не хуже.Всё же согласитесь, какого-то тотально-массового падения скриптов QLua явно не наблюдается.
Вы не смотрели мою программу, но голословно утверждаете: обычные скрипты могут нагрузить "автоматческую память" ничуть не хуже.
Цитата
swerg написал: зачем вы в каждой ветке обсуждаете свою проблему, притом что эта проблема никак не связана с темой ветки?
Вы гарантируете, что в управлении автоматической памятью QLua 5.3 нет ошибок синхронизации? А если есть такие ошибки, то в любых скриптах, в произвольные моменты времени могут возникать различные ошибки. И тогда это не моя, а общая проблема неустойчивости QUIK и, наверное, это не запрещено обсуждать и в данной ветке. Кстати, как решать мои проблемы меня учить не надо.
Цитата
swerg написал: полностью решённая в исходниках Lua. Там просто можно включить режим сборки "многопоточный". Ну так, если совсем упрощённо.Так что всё "от производителя".
Вы внимательно изучили исходники, например, Lua 5.3.5?? Интересно, где вы там нашли, что при включении режима сборки "многопоточный" будет реализована потокобезопасная сборка мусора?
TGB написал: есть ли понимание у разработчиков QUIK, что при существующей архитектуре обработки событий в QLua, уборка мусора в нем должна быть потокобезопасной?
Мне казалось, что заданный вопрос простой и для разработчиков QUIK понятный. Но так как ответа до сих пор нет, то я этот вопрос сформулирую более детально.
Текущая архитектура обработки событий в QLua (на 15.12.20), насколько я себе представляю, схематически следующая. Для обработки всех скриптов пользователя создается один служебный поток (под потоком здесь и далее понимается поток Windows). В этом потоке выполняется запуск всех скриптов пользователя, а также запуск колбеков всех выполняемых скриптов. Кроме того, в этом же служебном потоке будут созданы (при запросе из скриптов пользователя) пользовательские таблицы, а так же будут выполняются функции обслуживания всех таких таблиц (что, вообще то, является ошибкой, и, по-хорошему, это следовало бы отделить от обработки колбеков событий фондового рынка). При запуске каждого пользовательского скрипта в отдельном, в основном lua_State создается с помощью функции lua_newthread стек(State) сопрограммы и уже на нем запускается, в отдельном потоке, пользовательская функция скрипта main. Таким образом, исполнение функции main, по ее локальным объектам, пространственно отделено от основного lua_State. Отработка колбеков всех запущенных скриптов пользователя выполняется следующим образом. При возникновении события служебный поток запускает последовательно соответствующие событию колбеки выполняющихся скриптов. Колбеки выполняются в основных lua_State скриптов. При этом работают пользовательские потоки (main на стеках сопрограмм) всех выполняющихся скриптов. Таким образом, получается, что в скриптах пользователя могут работать два потока. Это поток пользователя (main) и служебный поток обработки колбека пользователя. Хотя локальные объекты потоков main пространственно отделены от основных lua_State скриптов и при работе с ними, в этих потоках синхронизация не требуется, но общим для работающего потока main и служебного потока, обрабатывающего его колбек, являются информационные структуры управления автоматической памятью QLua. Поэтому это управление должно быть потокобезопасным, то есть обеспечивать корректную работу нескольких потоков. Известно, что нативные версии Lua однопоточные. Управление автоматической памятью в них тоже однопоточное. Поэтому при внедрении версий Lua в QUIK требуется, наверное, много чего, но, как минимум, необходима переработка автоматического управления памятью с целью обеспечения ее потокобезопасности. И это сложная задача. --------------------------- Моя программа, на которой «падает» QUIK, тестирует автоматическую память QLua. Похоже, что эта память реализована некорректно, а значит в любых скриптах, в произвольные моменты времени могут возникать ошибки. Так как мой тест специально создает очень большую нагрузку на управление автоматической памятью, то ошибки возникают в течении 2-3 минут. При обычной работе эти ошибки возникают реже и могут проявляться в разных местах.
Вопросы к поддержке: 1) что из выше написанного мною неправильно? 2) есть ли понимание у разработчиков QUIK, что при существующей архитектуре обработки событий в QLua, уборка мусора в нем должна быть потокобезопасной?
Новая версия QUIK 8.11.0.66 (QLua 5.3) продолжает «падать» ( CQ02750791, CQ02779753, CQ02787899. CQ02802279) (CQ02809006)
Могу прислать поддержке дампы. Но с помощью посланной 15.08.20 вам мною моей программы, вы можете получать этих дампов столько, сколько захочете. Кроме того, наблюдается утечка памяти. На всякий случай ссылка на мою программу: https://cloud.mail.ru/public/5iZb/2NSAPmJem Вопрос к поддержке: 1) ответьте, пожалуйста, зачем устраиваются скачки с новыми версиями Lua (очередная 5.4)? Какие проблемы при этом решаются? 2) есть ли понимание у разработчиков QUIK, что при существующей архитектуре обработки событий в QLua, уборка мусора в нем должна быть потокобезопасной?
У ARQA, существует три варианта, после перехода на Lua 5.3, порождающем множество проблем и не предоставляющем, по большому счету ничего нового: 1) отказаться от перехода на Lua 5.3 и у них для этого было железное алиби (Lua является фактически двухуровневым языком и все, что не реализуемо в собственно Lua 5.1, можно реализовать в C/C++, с которым Lua тесно интегрирован): причем,. фактором усиливающим озвученное алиби, могло быть соображение, состоящее в том, что они заботятся о стабильности среды разработки, предоставленной пользователям; 2) "пробиться" через возникшие проблемы перехода на Lua 5.3, одной из которых является необходимость реализации, при сохранении существующей архитектуры обработки событий QUIK, многопоточности QLua 5.3 (по сравнению с однопоточностью нативного Lua 5.3); 3) изменить схему обработки событий QUIK так, чтобы уйти от проблем многопоточности QLua. На первый вариант они не пошли (и, по-моему, зря), а теперь и не могут пойти (ведь кому-то, и не рядовым, за это пришлось бы отвечать). Со вторым вариантом, похоже, возникли проблемы, которые наблюдают многие пользователи. Третий вариант, описанный мною в этой ветке, действительно, качественно меняет архитектуру QUIK, при которой: 1) исчезает требование многопоточности QLua (большой геморрой при переходе на новые версии Lua, в том числе на 5.3.5); 2) обеспечивается независимость основного потока регистрация событий от пользовательского "произвола", возникающем при использовании коллбеков, в которых "непросвященный" пользователь может делать все, что угодно. ------ Интересно, что нас ждет? Вопрос к поддержке: когда появится очередная новая версия QUIK?
<code> local run = true local tid = nil local file
--- Создание деструктора скрипта ----- gcrunner = {} --- Если gcrunner = {} (глобальная переменная), то __gc срабатывает только по завершению скрипта (обычно это и требуется). --- !!! А если local gcrunner = {} (локальная переменная) то __gc срабатывает при при любом запуске collectgarbage (в том числе, и до завершения скрипта). setmetatable(gcrunner, { __gc = function() if tid then DestroyTable(tid) end ---- Выделенный ниже фрагмент срабатывает при запуске collectgarbage до завершения скрипта если gcrunner локальная переменная. -- При запуске функции по заверщению скрипта, выделенный фрагмент не выполняется. Функция завершается на первом операторе --- без его выполнения, но ошибка не выдается ?? file:write("__gc\n") file:close() ---- Похоже при завершении скрипта файлы открепляются раньше, чем запускается финальная уборка мусора---- end }) ---------------------------------------------------
function OnInit(script_path) file = io.open(script_path .. ".log", "w") file:write("OnInit\n") end
function main() file:write("main\n") tid = AllocTable() AddColumn(tid, 1, '1', true, QTABLE_INT_TYPE, 1) CreateWindow(tid) -- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. while run do sleep(300) end file:write("main stopped\n") end
function OnStop() run = nil file:write("OnStop\n") end </code>
s_mike@rambler.ru написал: вообще qlua при завершении скрипта сама закрывает файлы. Видимо файл был закрыт до __gc
Похоже так оно и есть.
<code> local run = true local tid = nil local file
--- Создание деструктора скрипта ----- gcrunner = {} --- Если gcrunner = {} (глобальная переменная), то __gc срабатывает только по завершению скрипта (обычно это и требуется). --- !!! А если local gcrunner = {} (локальная переменная) то __gc срабатывает при при любом запуске collectgarbage (в том числе, и до завершения скрипта). setmetatable(gcrunner, { __gc = function() if tid then DestroyTable(tid) end ---- Выделенный ниже фрагмент срабатывает при запуске collectgarbage до завершения скрипта если gcrunner локальная переменная. -- При запуске функции по заверщению скрипта, выделенный фрагмент не выполняется. Функция завершается на первом операторе --- без его выполнения, но ошибка не выдается ?? file:write("__gc\n") file:close() ---- Похоже при завершении скрипта файлы открепляются раньше, чем запускается финальная уборка мусора---- end }) ---------------------------------------------------
function OnInit(script_path) file = io.open(script_path .. ".log", "w") file:write("OnInit\n") end
function main() file:write("main\n") tid = AllocTable() AddColumn(tid, 1, '1', true, QTABLE_INT_TYPE, 1) CreateWindow(tid) -- collectgarbage () --- Если эту строку раскомментировать и при этом local gcrunner = {}, то при запуске collectgarbage () сработает __gc. while run do sleep(300) end file:write("main stopped\n") end
function OnStop() run = nil file:write("OnStop\n") end <code>
Владимир написал: А как передаются параметры в Lua, мне АБСОЛЮТНО до лампады - я не разработчик языка, я просто пользователь. Просто ЕСЛИ они передаются не ссылкой, а самой таблицей значений, ТО это есть идиотизм.
Мне кажется, что вы зря "наезжаете" на язык Lua. Переключесть на C++ и будет вам счастье (и это обеспечивает Lua). Все, что вы не можете реализовать в собственно Lua (а это то очень мало), вы можете реализовать в C++.
Nikolay написал: Не думаю что пойдут на изменение синтаксиса. Я бы больше ожидал стабильности и предсказуемости в вызовах. Сейчас только несколько колбеков типа подключения-отключения-ответ транзакции можно использовать.Остальные не вызывают доверия и надежней баз них. А то когда у тебя колблек от событий прошедших часы назад прилетает после перезапуска терминала, то проще не смотреть на них.
ARQA, имхо, придется, скорее всего, пойти на изменения API по следующе причине: 1) проблеме реализации многопоточности QLua 5.3, которую они не смогли решить до сих пор (с марта 2020 до ноября 2020г.).
Владимир написал: nikolz , Исторические данные отличаются от реальных лишь тем, что берутся из файла (из БД), а не поступают в реальном времени от того же Квика, а потому алгоритм, который хорошо работает на исторических данных будет столь же хорошо работать и на данных реальных ....
К сожалению, реальные процессы фондового рынка очень далеки от формальных вероятностных моделей стохастистичеких процессов. Те метрики (средние, и многие другие), используемые пользователями для обеспечения прибыли на фондовом рынке, берутся за основу по причине отсутствия моделей неопределенных социальных процессов. На самом деле, то, что происходит на фондовом рынке это поведение толпы, жаждующей прибыли. При этом существенными факторами являются:
2) его виртуальность – это представления у участников рынка о том, что надо учитывать (иногда очень далекие от действительности);
3) инсайдерская составляющая (знание того, что скорее всего произойдет, отдельными участниками фондового рынка с существенными ресурсами), особенно значимая для России;
4) малипуляционная составляющая, присутствующая на всех рынках (в виде различных «вбросов» в СМИ и т.д.);
5) полная зависимость фондового рынка от поведения его участников (в том числе от использования новых информационных технологий);
6) паническое поведения толпы участников фондового рынка при его значительных колебаниях.
Все выше перечисленное выше существенно зависит от меняющегося текущего политико – экономической состояния локальных фондовых рынков. Поэтому иллюзии использования истории поведения фондового рынка (особенно в далеком прошлом) для получения прибыли, во многом, несостоятельны.
Александр М написал: Есть продукт, за который мы платим. По данному продукту есть проблема. Я как клиент имею полное право завести проблему и получить по ней информацию. Причем полную информацию
Наверное, если ARQU заинтересована в расширении своей клиентской базы и повышении ее лояльности, то в интересах разработчика QUIK как-то улучшать и упорядочивать работу с клиентами (пользователями). Александр М предлагает вариант таких изменений. Зачем от этого отмахиваться?
Anton написал: Если окно никуда не прицеплять, будет просто отдельное от квика окно. Чтобы окно было внутри квика, надо SetParent ему сделать с
=============================================
Цитата
TGB написал: Рассмотрим случай, когда при работе с таблицей, на неё "навешана" богатая функциональность, например, выполняемая 5 минут. Это значит, что все события, возникающие на рынке в интервале 5 минут недоступны для обработки в скрипте пользователя. Это хорошее поведение программы? Кто даст гарантии, что такая ситуация не возникнет.
Вы согласны что описанная выше ситуация может возникнуть? А если согласны, то сделать так, чтобы этого не возникало, задача ARQU. Если бы такая задача возникла у меня, я бы ее решил. Заниматься парным программированием здесь я не вижу смысла.
Anton написал: т.к. потоки будут синхронизироваться и ждать обработки сообщений друг друга;
Зачем потоку, обрабатывающего коллбеки рынка, синхронизироваться с потоком обрабатывающим таблицы? И вообще, для пользователя важно удобство при создании его скриптов, а как это сделать, это задача разработчиков QUIK.
Статья хорошая, но в ней особо предупреждается о проблемах реализации межпроцессорного взаимодействия. Я же пишу о потоках и не вижу особых проблем взаимодействия между ними. И это не только мои теоретические представления, но моя практика.
Владимир написал: TGB , Да и колбеки не хило бы там же обрабатывать. Что мы ловим? Скорость?
Рассмотрим случай, когда при работе с таблицей, на неё "навешана" богатая функциональность, например, выполняемая 5 минут. Это значит, что все события, возникающие на рынке в интервале 5 минут недоступны для обработки в скрипте пользователя. Это хорошее поведение программы? Кто даст гарантии, что такая ситуация не возникнет. Есть же известный принцип (и не только в программировании): не сваливай все в одну кучу.
В существующей реализации работы (из QLua с) таблицами QUIK есть существенный недостаток (а на самом деле, баг) состоящий в том, что такие таблицы обслуживаются в том же основном потоке, в котором запускаются коллбеки. Давно надо было бы сделать обработку обсуждаемых таблиц в отдельном потоке.
swerg написал: И вот на какой вопрос я при этом не нахожу ответа. Если бы не было main() - каким образом останавливать обработку колбеков, когда автор скрипта уже не хочет чтобы колбеки вызывались? ну вот в самом деле, нельзя же все время для всех скриптов вызывать колбеки. Или можно?
Попробую ответить кратко, как, это, похоже, происходит сейчас в QUIKе. Основной поток запуска и обслуживания пользовательских скриптов (в том числе и его коллбеков) при запуске любого скрипта сканирует его в поисках его же коллбеков (по именам событий). По каждому скрипту ведется список найденных его меток (функций) колбеков в рамках его lua_State. При возникновении любого события, основной поток обходит последовательно lua_State всех запущенных скриптов и запускает (если находит) соответствующие коллбеки. При останове любого скрипта порождается событие <OnStop>, которое отрабатывает также основной поток. При этом список коллбеков остановленного скрипта обнуляется.
Александр написал: В третьем варианте все будет выполняться в одном потоке и привет переписывание скриптов.
Вообще говоря, я сторонник первого варианта (щадящего пользователей), но он уже не реален. Если разработчики что-то изменят в работе с коллбеками, то пользователям, скорее всего, все равно придется что-то править в своих скриптах. В третьем варианте, в отличие от второго, есть хоть какой-то смысл.
swerg написал: Свежие мечтатели к нам подключились, похоже :))
Это я к себя не отношу, но использую, как повод высказаться дополнительно. У ARQU, существует три варианта, после перехода на Lua 5.3, порождающем множество проблем и не предоставляющем, по большому счету ни чего нового: 1) отказаться от перехода на Lua 5.3 и у них для этого было железное алиби (Lua является фактически двухуровневым языком и все, что не реализуемо в собственно Lua 5.1, можно реализовать в C/C++, с которым Lua тесно интегрирован): причем,. фактором усиливающим озвученное алиби, могло быть соображение, состоящее в том, что они заботятся о стабильности среды разработки, предоставленной пользователям; 2) "пробиться" через возникшие проблемы перехода на Lua 5.3, одной из которых является необходимость реализации, при сохранении существующей архитектуры обработки событий QUIK, многопоточности QLua 5.3 (по сравнению с однопоточностью нативного Lua 5.3); 3) изменить схему обработки событий QUIK так, чтобы уйти от проблем многопоточности QLua. На первый вариант они не пошли (и, по-моему, зря), а теперь и не могут пойти (ведь кому-то, и не рядовым, за это пришлось бы отвечать). Со вторым вариантом, похоже, возникли проблемы, которые наблюдают многие пользователи. Третий вариант, описанный мною в этой ветке, действительно, качественно меняет архитектуру QUIK, при которой: 1) исчезает требование многопоточности QLua (большой геморрой при переходе на новые версии Lua, в том числе на 5.3.5); 2) обеспечивается независимость основного потока регистрация событий от пользовательского "произвола", возникающем при использовании коллбеков, в которых "непросвященный" пользователь может делать все, что угодно. Этот вариант был бы достойным выходом для ARQU из сложившийся ситуации.
В упомянутой выше ветке мною был написан прогноз-предложение возможных изменений. Так как он относится и к тому, что обсуждалось в данной ветке, то приведу его текст здесь с небольшим добавлением.
-------------
Я не знаю точно, какие изменения будут, но попытаюсь дать прогноз (интересно, насколько промахнусь). А если промахнулся, то это мои предложения.
Видимо это будут изменения, которые надо было внести в схему обработки коллбеков QLua, как мне кажется, давно, а именно:
1) вместо регистрации функций обратного вызова, регистрация соответствующих очередей событий (возможно, с теми же именами); я бы сделал эти очереди циклическими, с указанием их длины при регистрации, но не более некоторого значения;
2) вместо sleep, служебная функция ожидания либо истечения интервала времени (как в sleep), либо появления данных в очередях событий (с выдачей списка непустых очередей);
3) добавление функции чтения очередей событий (их параметров).
Эта схема реализует рекомендованную ARQU обработку параметров событий в main. Кроме того, в такой схеме решается тяжелая задача подключения новых версий Lua в QUIK, так как не будет требоваться переработка в Qlua нативного управления автоматической ее памятью с целью реализации потокобезопасной уборки мусора, требуемой в старой схеме (из-за запуска функций коллбеков в потоке, отличном от потока main, но в контексте пользователя). Подключение новых версий Lua (в том числе и 5.3.5) станет в описанной выше схеме рутинной задачей.
Если будет реализована описанная выше схема обработки коллбеков, то, так как реализация QLua станет однопотоковой, мой многопотоковый тест памяти QLua для этого случая не применим.
swerg написал: Да не будет там изменений, что вы так переживаете. С чего вдруг?
Я не знаю точно, какие изменения будут, но попытаюсь дать прогноз (интересно, насколько промахнусь). А если промахнулся, то это мои предложения.
Видимо это будут изменения, которые надо было внести в схему обработки коллбеков QLua, как мне кажется, давно, а именно:
1) вместо регистрации функций обратного вызова, регистрация соответствующих очередей событий (возможно, с теми же именами); я бы сделал эти очереди циклическими, с указанием их длины при регистрации, но не более некоторого значения;
2) вместо sleep, служебная функция ожидания либо истечения интервала времени (как в sleep), либо появления данных в очередях событий (с выдачей списка непустых очередей);
3) добавление функции чтения очередей событий (их параметров).
Эта схема реализует рекомендованную ARQU обработку параметров событий в main. Кроме того, в такой схеме решается тяжелая задача подключения новых версий Lua в QUIK, так как не будет требоваться переработка в Qlua нативного управления автоматической ее памятью с целью реализации потокобезопасной уборки мусора, требуемой в старой схеме (из-за запуска функций коллбеков в потоке, отличном от потока main, но в контексте пользователя). Подключение новых версий Lua (в том числе и 5.3.5) станет в описанной выше схеме рутинной задачей.
Владимир написал: Ну... я бы тоже не отказался от С-подобного синтаксиса (например, JS)
Эта достаточно легко решаемая задача. Пишется простенький собственный препроцессор (на том же Lua), который в нужных местах заменяет "}" на "end" и убирает открывающие скобки "{" блоков ( при этом, конечно, надо учесть синтаксис задания таблиц, а может быть и еще что-то, например, "do") и после этого можно писать Lua-программы на синтаксисе в чем-то похожем на синтаксис C, обрабатывая их таким препроцессором.
В защиту удачного выбора ARQU пользовательского языка программирования Lua можно сказать следующее.
1. Фактически Lua является двухуровневым языком благодаря архитектурной (изначально) тесной его интеграции с C/C++. Это обеспечивает два уровня его использования:
1) начальный, достаточный для многих пользователей (базовый синтаксис Lua может быть описан на нескольких страницах);
2) расширенный с выходом в системный язык программирования C/C++ (и для этого в Lua есть C-API), на котором можно написать все что угодно.
Все проблемы, не решаемые в собственно Lua, могут решаться в C/C++. Нужна высокая производительность, переходим в C/C++. Нужен типизированный язык переходим туда же. Не хватает каких-то функций, переходим туда же.
2. Зачем вносить какие-то изменения в Lua с тем, чтобы из него сделать плохой C, когда и так можно писать на C?
3. Интересно то, что Владимир и сам не хочет писать ни на каком языке, кроме Lua.
А от куда берутся деньги на зарплату сотрудникам ARQU и вознаграждения ее акционерам? Оплата пользователями QUIK входит (косвенно) в те комиссии, которые пользователи платят своим брокерам.
Похоже, им все понятно. И это главное. Они разработчики QUIK. От них я вопросов не получаю (даже после моих неоднократных назойливых сообщений: а нет ли ко мне каких-либо вопросов?). С ними я готов обсуждать любые проблемы и они знают адрес моей почты.
Anton написал: нужно показать, что либо а) коллектор собирает объекты, не помеченные мусорными, либо б) коллектор не собирает объекты, помеченные мусорными. Ничего такого пока показано не было. Все остальное это уже не вопрос управления автоматической памятью
А может быть, вместо ARQU, мне написать и всю потокобезопасную Lua - машину, встроенную в QUIK? Для тех, кто понимает, это очень большие деньги за выполнение такой работы (как минимум: 7 месяцев * <Среднее количество разработчиков> * <Среднюю зарплату>). Как это сделать я понимаю. Но в любом случае, это сложная работа (и не всеми реализуемая), и я сочувствую разработчикам QUIK, "парящимся" над тем, как реализовать потокобезопасную уборку мусора QLua. Даже мой "хилый" тест (который, похоже, не был реализован ARQU за десятилетия своего существования хоть в каком-то виде), позволяющий, в оперативном режиме тестировать автоматическое управление памятью QLua, при его заказе на стороне, стоил бы, наверное, больших денег. Я его выслал поддержке QUIK без предоплаты.
Anton написал: повреждение памяти это вторичное явление и ковырять коллектор суть пустая
Цитата
TGB написал: Представьте, что вы купили ПК, в котором часто сбоит RAM (память). Это значит, что любые ваши программы могут «падать» в любом месте, в любое время и можно искать в них свои ошибки до «посинения». При этом, при работе на бирже, вы не можете отойти от ПК ни на минуту, так как ваша «автоматизация» может «упасть» в любой момент времени, возможно, с неприятными для вас последствиями.
P.S.Версиях QUIK < 8.5 мой тест управления автоматической памятью QLua ошибок не обнаруживает.
Все версии QUIK >=8,5 "падают" при запуске моего теста автоматической памяти QLua в интервале пяти минут. Интересно, кому непонятно что это фундаментальная проблема нестабильности QLua (кроме аффилированных с ARQU лиц)?
TGB написал: Вопросы к поддержке QUIK:. У вас "новичок" является внештатным сотрудником ARQU? А если это не так, то зачем вы тут (на форумах ARQU) его держите?
TGB написал: тест управления автоматической памятью QLua диагностирует утечку памяти и некорректность ее функционирования
Наверное, стоит пояснить, что означает приведенная выше цитата.
1. Это общая проблема для всех тех, кто использует скрипты QLua (возможно??, за исключением тех, кто вообще не использует служебные функции QLua).
2. Это порождает «плавающие», случайно возникающие ошибки в QLua-скриптах.
Представьте, что вы купили ПК, в котором часто сбоит RAM (память). Это значит, что любые ваши программы могут «падать» в любом месте, в любое время и можно искать в них свои ошибки до «посинения». При этом, при работе на бирже, вы не можете отойти от ПК ни на минуту, так как ваша «автоматизация» может «упасть» в любой момент времени, возможно, с неприятными для вас последствиями.
P.S. Версиях QUIK < 8.5 мой тест управления автоматической памятью QLua ошибок не обнаруживает.
Новая версия (от 05.10.20 ) QUIK 8.9.0.107 продолжает «падать» ( CQ02750791, CQ02779753, CQ02787899. CQ02802279) (CQ02809006)
Здравствуйте! Посылаю вам дамп. С помощью посланной 15.08.20 вам мною моей программы, вы можете получать этих дампов столько, сколько захочете. Кроме того, наблюдается утечка памяти.
---------
Ответ поддержки.
Добрый день.
Проблемой занимаемся, если будут дополнительно вопросы, то мы сообщим. Извиняемся за долгий разбор, постараемся ответить, как можно скорее.
TGB написал: Какуя версию QUIK Вы используете? Если >= 8.5, то можете посмотреть мой комментари
Странно, конечно, не все ситуации в QUIK возникают из-за сбоев управления автоматической памятью QLua 5.3.5, однако, меня поражает, что многие, похоже, не понимают, что, если сбоит память QLua 5.3.3, то можно ожидать всего что угодно, в любых своих программах.