1 (2020-10-27 16:54:15 отредактировано swerg)

Тема: StaticVar: Обмен данными между Lua-скриптами в QUIK

Сейчас каждый Lua-скрипт в QUIK запускается на своей, полностью изолированной витруальной машине, какое-либо взаимодействие между скриптами штатно не предусмотрено.

Баловства ради подумываю сделать dll-ку, которая бы позволяла передавать данные (хранить общие данные) для разных Lua-скриптов в QUIK.
Вижу это по-простому: каждый скрипт, который хочет иметь доступ к обзим данным, подключает себе DLL-ку, и записывает/читает из этого единого хранилища данные, доступные всем скриптам (по строковому имени, например). Наружу можно в виде таблицы изобразить, например. Или просто методы Set/Get по текстовому имени сделать. Можно пожалуй и между запусками скриптов данные хранить научиться, а на диск в файл сохранять/читать... расфантазировался я чего-то )

Уведомления об изменении значения? мороки много подписки делать, нотификаторы. Не знаю, надо ли?

В общем интересно узнать: надо ли кому-то такое?

2 (2023-06-28 09:50:37 отредактировано swerg)

Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

Версия 1.4.1

Ссылки для скачивания:

    Lua5.3: Если у вас уже были ранее скрипты,
    использующие эту библиотеку, по для работоспособности в Lua5.3 обязательно поправить:

       require("StaticVar")

    на

       stv = require("StaticVar")

    Возможности:

    Библиотека позволяет создать общее хранилище данных для нескольких Lua-скриптов, а также сохранять данные между запусками Lua-скрипта (в пределах одного запуска терминала QUIK!). Между запусками - сохраняйте в файлы самостоятельно.
    Каждый элемент сохраняется в виде пары "Назначаемое имя параметра" - "Значение".
    Поддерживается концепция "пространства имен" (Name Space): скрипт может назначить для себя текущий Name Space, после чего сохраняться и считываться данные будут только в пределах этого пространства. Имена данных, сохраняемых в разных Name Space, могут пересекаться, это будут разные данные. Если Name Space не назначен - используется "глобальное пространство" (по сути обособленное пространство имен nil). В любой момент текущее пространство имен может переключаться. (Name Space рекомендуется использовать только при надобности.)

    Поддерживаются функции:

    • SetVar("var_name", var_data) -- создает переменную с именем "var_name" в текущем Name Space и записывает в нее значение var_data; если передать только 1 параметр или второй параметр задать равным nil - значение с именем "var_name" будет удалено из хранилища

    • GetVar("var_name")   -- возвращает сохраненное значение с именем "var_name" из текущего Name Space; если переменной с указанным именем нет - вернет nil

    • UseNameSpace("NameSpace1") -- использовать пространство имен "NameSpace1"; если вызвать без параметров UseNameSpace() (или с пустой строкой "") - активным станет "неименованное" пространство имен; после старта скрипта Lua до вызова UseNameSpace с непустой строкой действует "неименованное" пространство имен

    • GetCurrentNameSpace() -- получить текущее пространство имен; возвращает строку, если какое-то пространство имет выбрано вызовом GetCurrentNameSpace, либо nil, если используется "неименованное" пространство

    • GetVarList()  -- возвращает таблицу формата ["имя_переменной"]=значение, содержащую все установленные (и не удаленные) значения для текущего пространства имен; надо понимать, если заполнено много переменных-данных - то таблица будет большая, и ее заполнение окажется накладными

    • SetVarList(table)  -- из переданной в качестве аргумента таблицы формата ["var_name"]=var_data заполняет данные с указанными именами в текущем пространстве имен; список сохраненных данных не заменяется, а лишь дополняется из таблицы

    • Clear()  -- удаляет все сохранённые значения для текущего NameSpace (потребовалась для тестов)

    • ClearAll()  -- все значения из всех NameSpace (потребовалась для тестов)

    Корректно сохраняются (из var_data) и считываются следующие типы Lua:

    • string

    • boolean

    • number

    • integer (int64) - для Lua5.3

    • table (любой вложенности)

    • данные остальных типов при сохранении преобразуется в строку "как получится".

    Ограничения:

    • передача данных между разными скриптами только в пределах одного процесса, т.е. одного QUIK;

    Изменения по версиям:
    1.4.1 - добавлено корректное сохранение типа Int64 при использовании в Lua5.3;

    1.4.0 - добавлена сборка x64 / Lua5.3 для QUIK 8.5;
    сборка x64 / Lua5.1 удалена, считаю использование версий QUIK 8.0...8.4 нецелесообразным.

    1.3.1 - Улучшено использование NameSpace в разных потоках: теперь если в main() задать NameSpace - то он активен только для потока main() этого скрипта и не влияет на код (на заданный NameSpace), выполняемый в основном потоке (или в потоке main() других скриптов). Т.е. NameSpace устанавливается в рамках каждого потока раздельно, что правильно для логики выполняемого кода.

    1.3.0 - добавлена сборка x64 / Lua5.1 для QUIK 8.0

    1.2.1 - исправлена ошибка сохранения не поддерживаемых типов данных

    1.2.0 - добавлена поддержка типа "таблица"; таблицы могут быть любой вложенности!

    1.1.0 - добавлено:

    • новый метод SetVarList()

    • корректно сохраняются/считываются данные с типами string, boolean, number; остальные типы преобразуются в string "как получится"

    1.0.0 - начальный вариант


    Спасибо s_mike@rambler.ru за тестирование самой первой версии и полезные предложения!


    Пожелания и предложения по функционалу, а также сообщения об ошибках всячески приветствуются.

    ToDo:

    • Задавать число в качестве "имени" переменной. По идее уже должно работать (с преобразованием имени в строку?), но надо проверить.

    • Добавить метод DelVar("var_name"), для красоты.

    • Добавить интерфейс "очередь". Методы PutQueue(QueueName, Data) - поместить данные в очередь, GetQueue(QueueName) - получить элемент очереди. Будет удобно для передачи "сообщений-данных", полными блоками, не придётся вводит флажки синхронизации

    • Значения "ключей" в Lua-таблицах могут быть любого типа: число, строка, таблица и т.д.; надо научиться корректно сохранять и восстанавливать значения "ключей" таблиц Lua. Сейчас ключи сохраняются как текст, какого бы исходно типа они не были, это неправильно.

    • Сделать возможность сохранения всего хранилища в файл и чтение из файла (в формате Lua-скрипта?).

    • (?)Сделать интерфейс обращения из Lua как к таблице; таблица индексируется с учётом типа ключа!

    • Сделать возможность инициирования запуска функции в рамках другого скрипта (т.е. реализовать какой-то механизм нотифицирования между скриптами): либо передавать функцию, какую надо исполнить, либо подписываться на call-back'и, либо передавать код callback-а.

    • Замутить передачу данных между несколькими терминалами на одной машине.

    Done:

    • (v.1.4.1)Для Lua5.3 сделать различимыми double (number) и int64 (integer).

    • (v.1.3.1) Заданное пространство имён должно работать в рамках потока! [url=https://quik2dde.ru/viewtopic.php?pid=2394#p2394]см. сообщение[/url]

    3 (2013-11-11 22:24:22 отредактировано swerg)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Пример 1. Исключительно тестовый.

    -- Файл test-1.lua 
    
    require("StaticVar")
    
    stv.UseNameSpace("testNS")
    
    function main()
        sleep(10000)
        stv.SetVar("xxx", "xxx-test-value")
        message("(test-1) " .. tostring(stv.GetCurrentNameSpace()) .. ".xxx=" .. tostring(stv.GetVar("xxx")), 1)
    end
    -- Файл test-2.lua 
    
    require("StaticVar")
    
    stv.UseNameSpace("testNS")
    
    function main()
        sleep(10000)
        message("(test-2) " .. tostring(stv.GetCurrentNameSpace()) .. ".xxx=" .. tostring(stv.GetVar("xxx")), 1)
    end

    Запускаем сначала test-1.lua, затем test-2.lua. Чрез 10 сек. Будет выведено 2 сообщения:

    (test-1) testNS.xxx=xxx-test-value  - первый скрипт сохранил значение и отобразил его
    (test-2) testNS.xxx=xxx-test-value  - второй скрипт отобразил значение, сохраненное первым скриптом

    4 (2013-11-11 22:31:51 отредактировано swerg)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    < reserved >

    5

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Буду признателен также за "примеры из жизни" по использованию этой библиотеки.

    Например, есть идея использовать библиотеку для связки "обычного" скрипта с роботом и скрипта, выводящего на графике какую-то информацию. Например, подобная связка двух скриптов [url=http://www.bot4sale.ru/download-categories/2012-06-13-15-10-36/item/sebestoimost-sdelok-na-grafike-quik.html]реализована здесь[/url], но пока без этой библиотеки.

    6

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    А есть какое-то ограничение на размер загружаемых таблиц? Мне удалось распарсить файл с историей сделок размером в 1мб и загрузить его в testNS, но с файлами размером хотя бы 50мб такое проделать уже не получается. Таблица в оперативной памяти до загрузки в  testNS весит 100мб,  но когда доходит до строчки stv.SetVar("data_table_NS",data_table) использование памяти квиком просто начинает постепенно расти до бесконечности. Как-нибудь можете это прокомментировать?

    7

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Какого-либо ограничения на размер нигде нет, кроме объема памяти. Но вероятно есть какие-то нюансы  в зависимости от объема данных и их структуры.
    Если пришлете данные для воспроизведения проблемы на swerg@swerg.ru - то обязательно  постараюсь разобраться.

    8

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Правильно я понимаю, что в целях экономии памяти на хранение одинакового массива данных в разных скриптах использование общего "пространства имен" бессмысленно? Т.к. требуемый объём памяти, наоборот, возрастает по сравнению с тем, если в каждом скрипте использовать свою переменную для хранения массива данных.
    Однако, доступ к элементам массива может значительно сократиться (в зависимости от структуры массива и типов данных).
    Всё верно?

    9

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    CyberTrader пишет:

    Правильно я понимаю, что в целях экономии памяти на хранение одинакового массива данных в разных скриптах использование общего "пространства имен" бессмысленно?

    Сэкономить как раз можно, пожалуй. Если объем данных в самом деле огромный. Ведь всё хранится 1 раз.

    CyberTrader пишет:

    Однако, доступ к элементам массива может значительно сократиться (в зависимости от структуры массива и типов данных).

    А вот для этого предпосылок решительно не вижу.

    10

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Мои суждения основаны исключительно на тестах.

    swerg пишет:

    Сэкономить как раз можно, пожалуй. Если объем данных в самом деле огромный. Ведь всё хранится 1 раз.

    Нам ведь не просто надо хранить данные. К данным необходимо обращаться.
    При использовании функции GetVar("var_name") резервирурется памяти больше, чем требуется просто для хранения массива данных в переменной.

    swerg пишет:
    CyberTrader пишет:

    Однако, доступ к элементам массива может значительно сократиться (в зависимости от структуры массива и типов данных).

    А вот для этого предпосылок решительно не вижу.

    Ну тут, как бы, при тестировании на определённом массиве данных с использованием общего "пространства имен" у меня получилось, что время доступа к элементам массива сократилось втрое.
    Я думал вам известно о таком "свойстве" библиотеки.

    11

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    CyberTrader пишет:

    Мои суждения основаны исключительно на тестах.

    Это очень здорово, но если бы вы привели тесты и применяемую вами методику изменения - можно было бы предметно обсудить/исправить.

    12

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Тестовых примеров, к сожалению не сохранилось.
    Но я стал писать новые тесты, и получил сообщение об ошибке:

    Unknown error. Possible unhandled exception.

    Код скрипта:

    require('StaticVar')
    
    stv.UseNameSpace("testNS")
    
    function main()
      local tab = {}
      for i = 1, 100000 do
        tab[i] = {i, os.time}
      end
      message('Таблица создана', 2)
      stv.SetVar('tab', tab)
    end

    Версия QUIK: 6.17.1.17

    13 (2015-07-24 16:22:30 отредактировано CyberTrader)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Ну ладно, с многомерными массивами не работает... Проверим на одномерном:

    Скрипт 1:

    function main()
      local tab = _CreateTable()
      while bRun do sleep(100) end
    end

    Скрипт 2:

    require('StaticVar')
    
    stv.UseNameSpace("testNS")
    
    function main()
      local tab = _CreateTable()
      stv.SetVar('tab', tab)
      while bRun do sleep(100) end
    end
    function _CreateTable()
      local tab = {}
      for i = 1, 1000000 do tab[i] = i end
      return tab
    end

    Скрипт 3:

    require('StaticVar')
    
    stv.UseNameSpace("testNS")
    
    function main()
      local tab = stv.GetVar('tab')
      while bRun do sleep(100) end
    end

    Тест без использования библиотеки (таблица создаётся в каждом запускаемом скрипте):
    1) Запускаем QUIK, смотрим в диспетчере задач занимаемую процессом info.exe
       Память: 32,0 Мб
    2) Запускаем две копии скрипта 1
       Память: 64,4 Мб

    Тест с использованием библиотеки (в одном скрипте создаётся таблица и помещается в Name Space, в другом скрипте эта таблица извлекается из Name Space):
    1) Перезапускаем QUIK
       Память: 32,1 Мб
    2) Запускаем скрипт 2
       Память: 93,4 Мб. И это без обращения к переменной "пространства имен" из 3-го скрипта.
    3) При получении значения сохранённой переменной из 3-го скрипта память, занимаемая процессом info.exe возрастает до 125,3 Мб.

    Как видно из результатов тестов, под переменную в Name Space дополнительно резервируется память, причём в большем объёме, чем требуется для той же переменной без использования Name Space.

    14 (2015-07-25 16:43:16 отредактировано kalikazandr)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    CyberTrader пишет:

    Как видно из результатов тестов, под переменную в Name Space дополнительно резервируется память, причём в большем объёме, чем требуется для той же переменной без использования Name Space.

    Так то оно так, только вы с помощью массива не одну переменную создаете, а 1 000 001 включая переменную 'tab'.
    Где вам в реалтайме понадобился такой массив с 1 млн ключей? считаю, что ваше "исследование", мягко сказать, не целесообразно.
    "StaticVar" прекрасно работает и цели, которые преследовались при ее создании уважаемым swerg, вполне достигнуты.

    15

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    CyberTrader, спасибо за подробный и обстоятельно оформленное сообщение.

    CyberTrader пишет:

    Ну ладно, с многомерными массивами не работает...

    Скажем так: для обхода многомерных конструкций используется тупая рекурсия, которая, как известно, очень любит потреблять стек (стек процессора, не Lua). И при глубоких вложенностях или большом количестве элементов стека может не хватать. На эту проблему уже жаловались, но тогда не был приведён пример, вы привели пример - это здорово, есть с чем разбираться, спасибо.


    CyberTrader пишет:

    Проверим на одномерном:

    По поводу полученных результатов. Положим что диспетчер задач показывает именно реальное наше потребление памяти, что не совсем корректно, но пусть в первом приближении это так.

    1) Запускаем QUIK, смотрим в диспетчере задач занимаемую процессом info.exe
       Память: 32,0 Мб
    2) Запускаем две копии скрипта 1
       Память: 64,4 Мб

    Отсюда можно сказать, что 2 наши большие таблицы занимают грубо 32 Мб в памяти Lua, т.е. по 16 Мб на таблицу.


    1) Перезапускаем QUIK
       Память: 32,1 Мб
    2) Запускаем скрипт 2
       Память: 93,4 Мб. И это без обращения к переменной "пространства имен" из 3-го скрипта.

    Немного не понял при чем тут "пространство имен", но грубо картинка такая, что мы
      а) создали 1 таблицу (это 16 Мб из предыдущего эксперимента)
      б) подгрузили библиотеку
      в) поместили её в буферное хранилище таблицу.

    В сумме пункты б) и в) заняли у нас грубо 93-32-16= 45 Мб.
    Ну например буферное универсальное хранилище не очень оптимально, что требует такого повышенного расхода памяти в сравнении с Lua.


    3) При получении значения сохранённой переменной из 3-го скрипта память, занимаемая процессом info.exe возрастает до 125,3 Мб.

    Т.е. прирост у нас грубо 125-93=32 Мб
    Из них 16 Мб - собственно копия таблицы Lua в вирт. машине скрипта 3, и 16 Мб - "накладных расходов", откуда они - хороший вопрос.

    Так я понимаю цифры вашего эксперимента.


    CyberTrader пишет:

    Как видно из результатов тестов, под переменную в Name Space дополнительно резервируется память, причём в большем объёме, чем требуется для той же переменной без использования Name Space.

    А вот эту вашу фразу я решительно не могу понять.
    Т.е. если убрать вот эту строку

          stv.UseNameSpace("testNS")

    то расход памяти уменьшится? или я не понимаю о каком Name Space вы говорите.

    16 (2015-07-26 09:46:54 отредактировано CyberTrader)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Изначально я предполагал, что "общее пространство имён" может быть реализовано в виде некоего "списка" указателей на переменные. Соответственно, создав один раз переменную (в данном случае, массив данных, only read) и добавив указатель на неё в "список" можно было бы использовать значение этой переменной в других скриптах, не расходуя дополнительно память под одни и те же данные.
    Но из теста стало понятно, что это не так, почему и написал выше:

    CyberTrader пишет:

    Правильно я понимаю, что в целях экономии памяти на хранение одинакового массива данных в разных скриптах использование общего "пространства имен" бессмысленно?


    swerg пишет:
    CyberTrader пишет:

    Как видно из результатов тестов, под переменную в Name Space дополнительно резервируется память, причём в большем объёме, чем требуется для той же переменной без использования Name Space.

    А вот эту вашу фразу я решительно не могу понять.

    Здесь я просто подвожу итог сравнения двух экспериментов:
    1-й без использования StaticVar, где в каждом скрипте создаётся свой массив данных и
    2-й, где в одном скрипте создаётся массив данных, помещается в "Name Space", а в другом скрипте извлекается из "Name Space"

    Итог таков (вы его привели выше в цифрах): на одну таблицу требуется 16 Мб памяти. Но если мы помещаем эту таблицу в буферное хранилище, то там она занимает уже 45 Мб (что больше 16 Мб).
    А с учётом:

    swerg пишет:

    Т.е. прирост у нас грубо 125-93=32 Мб
    Из них 16 Мб - собственно копия таблицы Lua в вирт. машине скрипта 3, и 16 Мб - "накладных расходов", откуда они - хороший вопрос.

    ни о какой экономии памяти в моём случае и речи быть не может.
    Кстати, провёл измерения второго теста далее:
    После остановки скрипта 2 процесс info.exe стал занимать 110 Мб. Из них: 32 Мб - сам процесс, 16 Мб - таблица в Lua в скрипте 3, 45 Мб - таблица в хранилище, остаётся, грубо говоря, неучтённых 16 Мб.
    Можно в скрипте 3 удалить таблицу из хранилища:

    function main()
      local tab = stv.GetVar('tab')
      stv.SetVar('tab')
      while bRun do sleep(100) end
    end

    Результат аналогичный: После остановки скрипта 2 процесс info.exe занимает 65 Мб: 32 Мб - сам процесс, 16 Мб - таблица Lua, 16 Мб-?

    Так что придётся в каждый скрипт грузить свою копию таблицы.

    [+]Spoiler

    Здесь я хочу отметить, что рабочий массив данных у меня занимает значительно больше, чем 16 Мб памяти, поэтому и стоит вопрос экономии. К тому же, при перезапусках QLUA-скриптов процесс info.exe не освобождает полностью выделенную ему память. В результате info "разбухает", что при большом количестве скриптов может закончиться ошибкой "not enough memory" из-за ограничения максимально выделяемого объёма памяти для 32-битных приложений.
    Если есть интерес я могу выложить скрипт и результаты тестов, показывающих, что по завершении скриптов память освобождается не полностью. Уж не знаю, чья это проблема: Квика иль ОС.

    17 (2020-10-27 19:25:27 отредактировано swerg)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    CyberTrader, теперь я вас понял.

    В StaticVar конечно-же создаётся копия данных, т.к. одной из основных идей было хранение данных между запусками скриптов.
    Если есть желание (надобность) хранить какой-то огромный набор общих данных и получать из него информацию в разных скриптах - наверное есть смысл несколько изменить парадигму и получать не целиком огромную таблицу в скрипт, а отдельные элементы (таблицы или просто отдельные именованные данные) в скрипты из единого общего хранилища.
    Правда тогда надо проводить эксперименты по поводу производительности и, быть может, допиливать эту самую производительность, если речь о доступе к элементам из таблицы с сотнями тысяч элементов.

    18 (2015-07-26 11:20:06 отредактировано CyberTrader)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    swerg пишет:

    одной из основных идей было хранение данных между запусками скриптов.

    Наверное, всё же "Обмен данными между Lua-скриптами в QUIK", т.к. для хранения данные лучше сбрасывать на диск.
    В этом случае моё предположение о создании списка указателей, а не копии данных, выглядело разумным.

    swerg пишет:

    наверное есть смысл несколько изменить парадигму и получать не целиком огромную таблицу в скрипт, а отдельные элементы (таблицы или просто отдельные именованные данные) в скрипты из единого общего хранилища.
    Правда тогда надо проводить эксперименты на счет производительности

    Т.е., динамически подгружать/выгружать необходимые данные?
    Уже проверил: производительность в моём случае падает существенно, т.к. сами операции SetVar/GetVar очень затратные, поскольку разговор идёт о создании копии данных.

    19

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Без копии невозможно и вот почему.

    В одном скрипте вызываем
          СохранитьЗначение("имя", перменная1)

    в другом скрипте через произвольный промежуток времени хотим вызвать
          переменная2 = ДайЗначение("имя")

    Но ведь перменная1 может быть локальной переменной функции, из которой давно уже вышли! Тогда на что указатель? а может уже и первый скрипт завершил свою работу.

    StaticVar создавалась именно под работу в таких условиях.
    Задача "давайте сделаем одно огромное хранилище данных, доступное в основном на чтение в разных скриптах" - несколько другая задача. Она, конечно, тоже решаема, но вероятно дизайн такого решения должен быть несколько иной.

    20 (2020-10-27 19:27:58 отредактировано swerg)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    CyberTrader пишет:

    Но я стал писать новые тесты, и получил сообщение об ошибке:

    Unknown error. Possible unhandled exception.

    Код скрипта:

    require('StaticVar')
    
    stv.UseNameSpace("testNS")
    
    function main()
      local tab = {}
      for i = 1, 100000 do
        tab[i] = {i, os.time}
      end
      message('Таблица создана', 2)
      stv.SetVar('tab', tab)
    end

    Оказывается, дело было совсем не в размере.
    Дело в том что os.time вот в такой записи - это функция. Т.е. в хранилище помещалась функция. Такой тип не поддерживается хранилищем, и была ошибка в обработке неизвестных типов, приводившая к краху. Т.е. падало (либо выводилось сообщение "Unknown error. Possible unhandled exception") даже вот на таком простейшем скрипте:

    require('StaticVar')
    
    stv.SetVar('tab', os.time)

    Эта проблема исправлена в версии 1.2.1.

    Хотелось бы отметить, что если всё же есть желание сохранить именно время, то необходимо после os.time поставить скобки:

    stv.SetVar('tab', os.time())

    Ну и в исходном скрипте тоже самое, надо добавить скобки, если таки хочется сохранить значение времени. Без скобок при сохранении в библиотеку StaticVar ничего не будет сохранено (вернее, сохранится nil), т.к. сохранения типа "функция" не поддерживается.

    21 (2015-07-30 23:59:42 отредактировано CyberTrader)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    swerg пишет:

    Хотелось бы отметить, что если всё же есть желание сохранить именно время, то необходимо после os.time поставить скобки

    Ну да, мой косяк, недосмотрел. Я ещё удивился - до этого с многомерным массивом работало.

    22 (2015-08-15 14:56:32 отредактировано kalikazandr)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    Уважаемый swerg,
    у меня через StaticVar общается несколько расчетных-скриптов со скриптом-координатором.
    Пока проблем не наблюдалось, потому что скрипт-координатор только получает данные от расчетных скриптов и в обратку ничего не отсылает.

    Возникла необходимость реализовать прямое общение:
    расчетный-скрипт <<-->> скрипт координатор

    stv.SetVar("flag", 0)--бездействие
    stv.SetVar("flag", nil)--база данных используется для чтения/ записи
    stv.SetVar("flag", 1)--расчетный-скрипт отправил сообщение для координатора
    stv.SetVar("flag", -1)--координатор отправил указание расчетному-скрипту


    if stv.GetVar("flag") == 0 then
      stv.SetVar("flag", nil)

        --только запись!

      stv.SetVar("flag", 1)
    end

    if stv.GetVar("flag") == -1 then--или 1
      stv.SetVar("flag", nil)

        --чтение и/или запись

      stv.SetVar("flag", 1)
    end

    Пока проблем не возникало, но! в состоянии ("flag", 0) может ли возникнуть ситуация, что оба скрипта считают флаг == 0 одновременно?

    23 (2015-08-15 15:56:40 отредактировано swerg)

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    kalikazandr пишет:

    Уважаемый swerg,

    Я вас умоляю!

    kalikazandr пишет:

    Пока проблем не возникало, но! в состоянии ("flag", 0) может ли возникнуть ситуация, что оба скрипта считают флаг == 0 одновременно?

    Смотря в какой части скрипта вписана эта проверка и последующий код.
    Если это обработчики событий в разных скриптах - то все обработчики выполняются строго последовательно в рамках основного потока QUIK, поэтому там проблем быть не может.
    Если этот код расположен внутри main() разных скриптов (или в хотя бы один скрипт содержит данную проверку в main()) - то, т.к. все main() разных скриптов выполняются параллельно (грубо говоря одновременно) в разных потоках, здесь уже могут быть коллизии, когда два скрипта одновременно выполнят проверку условия и для обоих скриптов окажется значение переменной одинаковым.

    24

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    swerg пишет:

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

    В колбеке скрипт-координатор начинает видеть, что какой-то скрипт организовал с ним связь через StaticVar.
    Все последующее общение происходит в main обоих скриптов.
    Конечно пока и при действующей конструкции не возникало "коллизий" из-за малой вероятности события, которое может привести к попытке одновременной записи в соответствующее поле StaticVar из разных скриптов.
    Наверное, есть смысл сделать два отдельных флага на чтение и запись и 2 соответствующих поля.
    Спасибо.

    25

    Re: StaticVar: Обмен данными между Lua-скриптами в QUIK

    kalikazandr а в чем проблема использовать внешнюю БД, для обмена данными?