Что если вызвать функцию CreateDataSource для создания источника данных (ИД) несколько раз? Функция вернёт ту же таблицу, что в предыдущий раз? Или каждый раз будет генерировать новую таблицу с новым ИД, где снова в коллбеке будут последовательно переданы все свечи, начиная с 1-й и до текущей?
Пользователь
Сообщений: Регистрация: 27.01.2017
11.12.2025 17:30:46
Если не путаю, то кеширования нет, так что это задача скрипта помнить, что уже заказано.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.12.2025 17:35:17
Предположу, что туже самую. Так как не возникал такой вопрос.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.12.2025 17:36:45
если создается другая, то она очевидно будет точной копией.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.12.2025 17:38:00
можно протестить, если разработчики не прояснят.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.12.2025 18:04:00
если вызывать так: local x=CreateDataSource(class, sec,1); то новая таблица будет просто удалять старую. -------------------- При повторном вызове создается новая таблица:
nikolz написал: если вызывать так: local x=CreateDataSource(class, sec,1); то новая таблица будет просто удалять старую. -------------------- При повторном вызове создается новая таблица:
написал: если вызывать так: local x=CreateDataSource(class, sec,1); то новая таблица будет просто удалять старую. -------------------- При повторном вызове создается новая таблица:
А предыдущие таблицы будут автоматически уничтожаться сборщиком мусора? Или они по-прежнему будут триггерить функцию-коллбек?
Нет. Эта таблица ничего не триггереет. Она просто содержит указатели на функции. Все затертые таблицы вообще становятся недоступными и их сборщик соберет.
Пользователь
Сообщений: Регистрация: 30.10.2024
12.12.2025 12:32:37
Цитата
nikolz написал: Эта таблица ничего не триггереет. Она просто содержит указатели на функции. Все затертые таблицы вообще становятся недоступными и их сборщик соберет.
Так значит предыдущая функция-колббек будет по-прежнему вызываться квиком?
написал: Эта таблица ничего не триггереет. Она просто содержит указатели на функции. Все затертые таблицы вообще становятся недоступными и их сборщик соберет.
Так значит предыдущая функция-колббек будет по-прежнему вызываться квиком?
Поясните вопрос. какие предыдущие? Вы что делаете кучу колбеков на один и тот же источник ? А нафига?
Пользователь
Сообщений: Регистрация: 30.01.2015
12.12.2025 13:03:04
Указатель на колбек записывается в таблицу. Если таблицу уничтожили, то и указатель уничтожен.
Пользователь
Сообщений: Регистрация: 27.01.2017
12.12.2025 13:09:19
Здесь вопрос более тонкий. Кеш сделали и ладно. Я бы не стал полагаться на GC, все же запомнить уже заказанные потоки не сложно. А вот закрытие оных уже вопрос. Я меня есть счетчик использования потоков. Т.к. один и тот же может использоваться много раз. И по мере того, как он перестает быть необходимым счетчик уменьшается, и если он 0, то вызывается Close. Дабы закрыть поток.
Но т.к. скрипт может быть остановлен принудительно, что закрыть все открытие потоки уже не всегда будет возможно. Как себя ведет терминал при таком закрытии скрипта - не ясно. Надеюсь, что есть внутренний кеш.. В древних версиях терминала (на ранней 7-ой, кажется) при заказе потоков без закрытия или вызова GC - терминал начинал есть память.
Пользователь
Сообщений: Регистрация: 30.10.2024
12.12.2025 13:15:18
Цитата
nikolz написал: Указатель на колбек записывается в таблицу. Если таблицу уничтожили, то и указатель уничтожен.
А вот и нет! Функция будет жить самостоятельно, если создана до таблицы, а в таблице только ссылка на таблицу.
Код
$ lua
Lua 5.4.8 Copyright (C) 1994-2025 Lua.org, PUC-Rio
> f = function(x) return x*x end
> f(6)
36
> t = {aaa = f}
> t.aaa(8)
64
> t = nil
> t.aaa(3)
stdin:1: attempt to index a nil value (global 't')
stack traceback:
stdin:1: in main chunk
[C]: in ?
> f(4)
16
написал: Указатель на колбек записывается в таблицу. Если таблицу уничтожили, то и указатель уничтожен.
А вот и нет! Функция будет жить самостоятельно, если создана до таблицы, а в таблице только ссылка на таблицу.
Код
$ lua
Lua 5.4 . 8 Copyright (C) 1994 - 2025 Lua.org, PUC - Rio
> f = function (x) return x * x end
> f( 6 )
36
> t = {aaa = f}
> t.aaa ( 8 )
64
> t = nil
> t.aaa ( 3 )
stdin: 1 : attempt to index a nil value (global 't' )
stack traceback:
stdin: 1 : in main chunk
[C]: in ?
> f( 4 )
16
А кто ее вызывать будет и как?
Пользователь
Сообщений: Регистрация: 30.10.2024
12.12.2025 13:50:30
Цитата
Nikolay написал: Здесь вопрос более тонкий. Кеш сделали и ладно. Я бы не стал полагаться на GC, все же запомнить уже заказанные потоки не сложно. А вот закрытие оных уже вопрос. Я меня есть счетчик использования потоков. Т.к. один и тот же может использоваться много раз. И по мере того, как он перестает быть необходимым счетчик уменьшается, и если он 0, то вызывается Close. Дабы закрыть поток.
Но т.к. скрипт может быть остановлен принудительно, что закрыть все открытие потоки уже не всегда будет возможно. Как себя ведет терминал при таком закрытии скрипта - не ясно. Надеюсь, что есть внутренний кеш.. В древних версиях терминала (на ранней 7-ой, кажется) при заказе потоков без закрытия или вызова GC - терминал начинал есть память.
Я думаю сделать так
Код
if sec.data_source then -- sec - торгуемый инструмент
sec.data_source:Close()
end
sec.data_source = _G[ 'CreateDataSource' ]( sec.class, sec.code, _G[ 'INTERVAL_M1' ] )
if not sec.data_source then
log.error( '...' )
end
Зачем закрывать, если он уже есть. Наоборот, просто вернуть существующий. Если закрыть поток, который в кеше и используется, то будет ошибка обращения.
Пользователь
Сообщений: Регистрация: 30.10.2024
12.12.2025 14:44:27
Цитата
Nikolay написал: Если закрыть поток, который в кеше и используется, то будет ошибка обращения.
А разве может быть ошибка при вызове Close() для непустого data_source? Конечный пользователь, опирающийся на руководство QLua, вообще не должен быть в курсе о внутренней кухне (кешируется там что-то или нет). Есть функция Close(), значит она должна всё корректно закрыть.
Пользователь
Сообщений: Регистрация: 27.01.2017
12.12.2025 15:44:03
Цитата
Сергей Че написал: А разве может быть ошибка при вызове Close() для непустого data_source? Конечный пользователь, опирающийся на руководство QLua , вообще не должен быть в курсе о внутренней кухне (кешируется там что-то или нет). Есть функция Close() , значит она должна всё корректно закрыть.
Во-первых, он уже может быть закрыт. А у Вас ссылка сохранена. Во-вторых, если этот поток в кеше был выдан по другому запросу, в вашем примере это другая таблица sec, то закрывая поток, об этом не узнаю другие пользователи этого потока.
Эта задача, похожа на задачу GC. Есть ссылка, её используют несколько потребителей. Соответственно закрыть ссылку можно только если счетчик использования 0.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.12.2025 10:49:47
Цитата
Nikolay написал: Здесь вопрос более тонкий. Кеш сделали и ладно. Я бы не стал полагаться на GC, все же запомнить уже заказанные потоки не сложно. А вот закрытие оных уже вопрос. Я меня есть счетчик использования потоков. Т.к. один и тот же может использоваться много раз. И по мере того, как он перестает быть необходимым счетчик уменьшается, и если он 0, то вызывается Close. Дабы закрыть поток.
Но т.к. скрипт может быть остановлен принудительно, что закрыть все открытие потоки уже не всегда будет возможно. Как себя ведет терминал при таком закрытии скрипта - не ясно. Надеюсь, что есть внутренний кеш.. В древних версиях терминала (на ранней 7-ой, кажется) при заказе потоков без закрытия или вызова GC - терминал начинал есть память.
Я полагаю, что эта таблица лишь хранит указатели, а не заказывает новые потоки. Поток данных будет один. Таблиц можно создать сколько угодно. Затраты копейки. Если это таблица не сохраняется как глобальная , то отсутствие на нее ссылки приведет к уничтожению ее сборщиком мусора.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.12.2025 11:55:46
Вот тест: ------------------- Запускаем QUIK Смотрим сколько потоков:
их 11 теперь стартуем скрипт который в main делает подписку много раз: Это лог файл таблиц, которые созданы по подписке
В рамках одного скрипта (торгового робота) понятно, что поток будет один. Хоть я 10 раз выполню CreateDataSource() с одними и теми же параметрами. А если разные скрипты (торговые роботы) решили поторговать одним и тем же инструментом?
В рамках одного скрипта (торгового робота) понятно, что поток будет один . Хоть я 10 раз выполню CreateDataSource () с одними и теми же параметрами. А если разные скрипты (торговые роботы) решили поторговать одним и тем же инструментом?
Реально подписку делает терминал а не скрипт, Скрипт это VMLua (виртуальная машина) . QLua - это и есть библиотека для связи скриптов с терминалом, а через него с сервером. Можно не делать никакую подписку, а открыть график в терминале это и вызовет обращение терминала к серверу за данными. Неважно сколько вы запустите скриптов по одному инструменту , сервер будет посылать свечи лишь в одном экземпляре. ------ А теперь тест: запускаем терминал: 18 потоков
1-ый скрипт
2-ой скрипт
это текст скриптов (изменяем имя log файла и имя скрипта)
Код
minfo=debug.getinfo(1, "S").source:sub(2); p=minfo:match("(.*[/\\])") or "."
logf =p.."/lua_log.txt" Log = io.open(logf,"w")
class = "QJSIM"
sec = "SBER" -- КОД ИНСТРУМЕНТА
local t={}
function main()
while true do
local x=CreateDataSource(class, sec,1);
local y=x;
Log:write(tostring(x).."\n");
Log:write(tostring(y).."\n");
sleep(1000);
end
end
это таблицы которые создали скрипты:
Пользователь
Сообщений: Регистрация: 30.01.2015
13.12.2025 18:46:14
запуск каждого скрипта добавляет ровно один поток - функция main.
Пользователь
Сообщений: Регистрация: 30.10.2024
13.12.2025 19:10:53
Цитата
nikolz написал: запуск каждого скрипта добавляет ровно один поток - функция main.
То есть сколько скриптов запрашивают поток, столько же потоков запрашивает КВИК? Даже на один и тот же инстумент?
написал: запуск каждого скрипта добавляет ровно один поток - функция main.
То есть сколько скриптов запрашивают поток, столько же потоков запрашивает КВИК? Даже на один и тот же инстумент?
нет. Когда запускается скрипт, то функция main запускается в отдельном потоке. Это делается для функции main, даже если в скрипте лишь эта функция пустая. так реализован механизм запуска скрипта.
написал: запуск каждого скрипта добавляет ровно один поток - функция main.
То есть сколько скриптов запрашивают поток, столько же потоков запрашивает КВИК? Даже на один и тот же инстумент?
нет. Когда запускается скрипт, то функция main запускается в отдельном потоке. Это делается для функции main, даже если в скрипте лишь эта функция пустая. так реализован механизм запуска скрипта.
Я не об этом. Есть 2 скрипта. У каждого своя функция main. Каждый скрипт запрашивает данные по одноиу и тому же инструменту на одном и том же таймфрейме. Сколько потоков создаст функция CreateDataSource()?
Пользователь
Сообщений: Регистрация: 12.05.2020
14.12.2025 16:12:45
Цитата
Сергей Че написал: Сколько потоков создаст функция CreateDataSource()?
Вы, наверное, хотели спросить: сколько хранилищ свечей создаст функция CreateDataSource()? Ответ: одно.
написал: Сколько потоков создаст функция CreateDataSource()?
Вы, наверное, хотели спросить: сколько хранилищ свечей создаст функция CreateDataSource()? Ответ: одно.
И что будет, если в одном из скриптов вызвать data_source:Close() ? Другой скрипт обломается?
Сергей Че, Вы что-то путаете Функция reateDataSource()? никакие потоки не открывает. Я вам это уже давно сказал. Вы опять пошли по кругу.
Пользователь
Сообщений: Регистрация: 30.10.2024
14.12.2025 17:24:12
Цитата
nikolz написал: Сергей Че, Вы что-то путаете Функция reateDataSource()? никакие потоки не открывает. Я вам это уже давно сказал. Вы опять пошли по кругу.
Ну окей, не "поток данных", а "источник данных", ведь именно так и переводится "CreateDataSource" - "Создать Источник Данных". Это что-то изменило для вас?
Пользователь
Сообщений: Регистрация: 30.01.2015
14.12.2025 17:24:33
, Рекомендую почитать про потоки и не только:
Пользователь
Сообщений: Регистрация: 30.10.2024
14.12.2025 17:59:43
Цитата
nikolz написал: , Рекомендую почитать про потоки и не только:
Спасибо за рекомандацию, но всё-таки, что произойдёт с ИД второго скрипта, если в первом выполнить data_source:Сlose(), учитывая, как было сказано выше, что хранилище свечей одно.