У кого возникнет такой же вопрос - http://quik2dde.ru/viewtopic.php?id=100 Коротко: один процесс на main() и второй на все callback-и - изменять глобальные переменные и оттуда и оттуда не стоит, можно получить непредсказуемые результаты.
Добрый день. Непредсказуемые результаты давало использование функций работы с таблицами - insert/remove. Простое изменение глобальных переменных из функций обратного вызова и main безопасно.
Если отвечать формально, то идентификатор сессии можно посмотреть в терминале, в информационном окне. Когда при подключении к серверу терминал получает новый идентификатор, то случается событие OnCleanUp(). Все возможные причины я перечислил выше.
При нормальных условиях работы "Смена даты торгов на сервере QUIK" является наиболее возможной причиной смены идентификатора сессии для терминала. Я перечислил все возможные случаи.
Добрый день. Идентификатор сессии может смениться при подключении терминала на другой сервер, смене торгового дня на сервере или рестарта сервера в течении дня с очисткой данных.
Удалось воспроизвести ситуацию. Для воспроизведения была специально написана dll, которая кидает исключение в экспортируемой функции.
Код
except = require('except')
function logger_error(str)
message(tostring(str))
end
function bad1()
x = except.zero_divizion()
return x
end
function bad2()
x = except.null_pointer()
return x
end
function err_handler(err)
logger_error("Logger: " .. tostring(err))
logger_error(debug.traceback())
end
function main()
res, msg = xpcall(bad1, err_handler)
if not res and msg then
logger_error("call bad1: " .. tostring(msg))
end
res, msg = xpcall(bad2, err_handler)
if not res and msg then
logger_error("call bad2: " .. tostring(msg))
end
end
результат выполнения в QUIK (стандартная Lua.exe просто разваливается)
При выполнении xpcall первой на стек кладется функция-обработчик ошибок. При возникновении критической ошибки, в данном случае ACCESS VIOLATION, работа завершается и мы наблюдаем вот такую картину. Попробуйте на время избавиться от использования socket, если она Вам нужна только для получения системного времени, и понаблюдать за поведением.
_sk_ пишет: Вряд ли без помощи разработчиков QUIK и сохранения ошибок луа-машины в некий дамп можно что-то конструктивное сделать. (В Java, например, если виртуальная машина по какой-то причине падает с внутренней ошибкой, пишется некий err-файл, где хоть какие-то подробности приводятся.)
Без примера кода не получится разобраться. Я, например, не смог за разумное время повторить ошибку. Можете прислать код целиком, это тоже поможет в разборе. Сохранять "дамп" не такая тривиальная задача как кажется. Например, как быть с различными данными типа userdata? Байт-код, состояние переменных и таблиц можно сохранить самому, все средства для этого у пользователя есть.
При инициализации Lua смотрит на две переменные - LUA_PATH и LUA_CPATH. Если Вы планируете загружать модуль как dll, то он должен находиться в package.cpath, если это код Lua, то package.path. Ошибка, которую Вы получаете, говорит о том, что Lua пытается загрузить dll как свой нативный код. Даже в Вашем примере "..\lib\mingw_dll\?.dll;;;;F :\ lua\5.1\lua\?.luac" смешаны файлы luac и dll. В общем Вам надо разобраться откуда что загружается и навести порядок в библиотеках и путях.
Дмитрий Минеев пишет: Добавьте маску c \путь\\?.dll в package.cpath Это уже сделано
Где-то не сходится.
Если Вы копируете библиотеки в папку со скриптом, то: package.cpath = getScriptpath() .. "\\?.dll;".. package.cpath Либо вместо getScriptpath добавьте правильный путь к библиотекам
Для некоторых параметров из ТТП невозможно построить источник данных. Например это параметры бумаги, которые отображаются в таблице(их можно получить из getItem("securities"...)) и так называемые перечислимые поля типа "статус сессии", "статус клиринга" и т.п.
Понятнее не стало. Какой ответ был на транзакцию? на каком рынке совершалась операция? В любом случае, заявка с нулевым trans_id допускается. Причины уже были описаны выше в этой ветке.
Алгоритмы обработки зависят от решаемых задач, тут сложно подсказать универсальный рецепт. Насчет разных флагов - можно сказать точнее если знать параметры транзакции и ответ торговой системы
Николай Камынин пишет: Если надо работать с очередями с 5000 элементов, то надо просто написать спец модуль такой очереди для луа на СИ. ------------------------------------------------- Я делаю именно так для обработки больших массивов, очередей, списков, пулов, ну и т д --------------------------------- Полагаю, что если чел смело берется за потоки с очередями в 5000 элементов, то создать спец модуль очереди для него - раз плюнуть.
Мне кажется что различные очереди в скрипте как раз проще делать на Lua.
Старатель пишет: Michael Bulychev , тогда тем более не понятно, почему за основу потокобезопасных функций вы взяли table.insert/table.remove, а не свой вариант.
Пример показывает, что insert/remove не оптимальное решение. Для подобных задач есть более оптимальные алгоритмы, одних из них был приведен на нашем форуме.
Юрий пишет: getSecurityInfo('',left.name).class_code
Искать код класса по коду бумаги не очень хорошая идея, можно запросто получить неверный результат. Судя по коду бумаги, проще явно указать код класса "SPBFUT"
Еще раз: дело не в нашей реализации, а в том как устроены оригинальные функции. При удалении первого элемента из массива, остальные элементы сдвигаются на индекс -1. Это значит что чем больше у вас исходная таблица, тем больше нужно времени на удаление первого элемента. Вот простой тест:
Код
local item = { 1, 2, 3, 4}
local _ins = table.insert
local _rem = table.remove
function remove_first(t)
return _rem(t, 1)
end
function prepare(t, item, size)
t={}
for i=1, size do
t[i] = item
end
return t
end
for s=500, 10000, 100 do
T = prepare(T, item, s)
_start = os.clock()
while remove_first(T) do end
_end = os.clock()
print(string.format("%d\t%.3f", s, (_end - _start)))
end
Все это выполняется не в терминале, а в обычном lua.exe. Результаты для наглядности в картинке:
Скрытый текст
Видно, что зависимость времени обработки от размера массива далеко не линейная.
Вопрос не в ситуации когда это происходит, а в разумности применения тех или иных функций. Что бы было понятнее - тутначало этой истории. На последней странице как раз есть пример очереди без блокировок.
Пользователям был нужен такой инструмент и они его получили. Как и всяким инструментом, им нужно пользоваться правильно и использовать к месту. Скорее всего в OnAllTrade Вы в конец добавляете сделки в конец массива, а при выгрузке в базу удаляете элемент с индексом 1. Ничего удивительного что все тормозит. Ваши тормоза не связаны не столько с синхронностью выполнения, сколько с особенностью реализации этих функций. Я уже на старом форуме и на этом рассказывал как устроены функции insert/remove. Также дважды приводил пример кода для неблокирующей очереди. Мне кажется, что если вы избавитесь от remove и просто будете запоминать последний обработанный индекс, пробивая обработанные элементы значением nil, то скорость будет гораздо выше.
DronGO пишет: Кстати table. s insert table. s remove, работают очень медленно, в сотни раз медленнее, чем lock-free системы. И в своей работе их использовать не стал.
200 это количество локальных переменных по умолчанию для одной функции. В этом месте QLua собрана без изменений
Код
/*
@@ LUAI_MAXVARS is the maximum number of local variables per function
@* (must be smaller than 250).
*/
#define LUAI_MAXVARS 200
причем это количество локальных переменных для одного блока кода
Код
MAX_LOCALS=arg[1] or 200
for i=1, MAX_LOCALS do
if i%10 ==0 then
io.write("\n")
end
io.write(string.format("local x%03d ", i))
end
io.write("\n")
print("function foo()\n")
io.write("\t")
for i=1, MAX_LOCALS do
if i%10 ==0 then
io.write("\n\t")
end
io.write(string.format("local x%03d ", i))
end
print("\n\treturn 1\nend\n")
print("function foo1()\n")
io.write("\t")
for i=1, MAX_LOCALS do
if i%10 ==0 then
io.write("\n\t")
end
io.write(string.format("local x%03d ", i))
end
print("\n\treturn 1\nend\n")
при MAX_LOCALS <=200 генерируется вполне рабочий код, который Lua может обработать. Хотя лично я не представляю себе осмысленного кода с таким количеством локальных переменных.
Дмитрий пишет: local Mdate=t[v].datetime.year..t[v].datetime.month..t[v].datetime.day label_params.DATE=Mdate local Mtime=t[v].datetime.hour..t[v].datetime.min..t[v].datetime.sec label_params.TIME=Mtime
Добрый день. дата и время передаются в форматах YYYYMMDD и HHMMSS соответственно.
math.huge is a constant. It represents +infinity.
> = math.huge
inf
> = math.huge / 2
inf
> = -math.huge
-inf
> = math.huge/math.huge -- indeterminate
nan
> = math.huge * 0 -- indeterminate
nan
> = 1/0
inf
> = (math.huge == math.huge)
true
> = (1/0 == math.huge)
true
Note that some operations on math.huge return a special "not-a-number" value that displays as nan. This is a bit of a misnomer. nan is a number type, though it's different from other numbers:> = type(math.huge * 0)
number
Добрый день. OnQuote вызывается на каждое изменение стакана, полученное с сервера. Если вы получите на терминал 1000 изменений с сервера и ваш скрипт обрабатывает 100 в секунду, то сетевая очередь на стороне клиента будет разобрана за 10 секунд.
Повторю еще раз - такое поведение сделано было осознанно. Есть задачи для которых удобно что-то посчитать, вывести табличку и остановить скрипт. При этом вся информация остается в терминале.
sam063rus пишет: Вам ли не знать, что такое QTable?
Это был пример на Lua который только в общих чертах описывает идею реализации таблицы как объекта. С точки зрения терминала это такая же таблица как и, например, таблица всех сделок.
Добрый день. Не совсем понимаю о чем Вы. Если об этом:
Цитата
sam063rus пишет: и последнее, стоит ли заниматься сабклассингом QTable-окна или есть реальная возможность таки дождаться полноценного GUI-support в QLUA?
То как я могу вам что-то запретить, хотя я не знаю что такое QTable в Вашем понимании. Планы по реализации поддержки GUI у нас есть, но сроки мы назвать пока не можем.
Например так: у брокера два независимых сервера QUIK и два комплекта шлюзов в торговую систему. Менеджер с другого сервера может поставить заявку за Вас, которая через торговую систему приедет на другой сервер без UID пользователя. Но на практике такая система не используется.