Тема: Исследование порядка вызовов Callback-функций в QLua
(Обновлено 28.12.2012 )
[url=https://quik2dde.ru/viewtopic.php?id=18]Как подключать свои DLL-модули к Lua (QLua) и вызывать из этой Dll свои функции[/url] - подробно написано в отдельной теме.
В данном случае подключить DLL мне понадобилось для того, чтобы получить доступ к WinAPI, в частности для исследования в каких потоках какие функции обратного вызова вызываются из QLua.
А сегодня вот о чем. Сделаем такой LUA-скрипт (полный исходник можно скачать по ссылке в конце этого поста):
local testc = require("testc")
f = nil
is_run = true
function writeTyreadID(proc_name)
f:write(os.date() .. " ".. proc_name .. ":" .. tostring(testc:GetCurrentThreadId()) .. "\n")
f:flush()
end
function OnInit(path)
f = io.open(path .. ".out", "w+t")
writeTyreadID("OnInit")
end
function OnStop(signal)
writeTyreadID("OnStop")
is_run = false
end
function main()
writeTyreadID("main start")
while is_run do
sleep(50)
end
writeTyreadID("main stop")
f:close()
end
-------------------
function OnAccountBalance(acc_bal)
writeTyreadID("OnAccountBalance")
end
function OnAccountPosition(acc_pos)
writeTyreadID("OnAccountPosition")
end
..........
Под чертой я просто вставил все обработчики, какие перечислены в документации.
Что мы тут видим: подключение внешнего модуля, потом типичная теперь уже функция main() и обработчики инициализации OnInit () и остановки скрипта OnStop, функция writeTyreadID() для записи в файл имени обработчика и ID потока, в рамках которого он вызван. За одно пишется время, чтобы было удобно потом смотреть что и когда происходило, сопоставлять. Идея всей этой затеи с логированием всех обработчиков была в том, чтобы обнаружить те из них, которые, возможно, вызываются в разных потоках, а значит обрабатываются параллельно.
В итоге в результате запуска и остановки скрипта получился такой лог, повторяющиеся строки я здесь вырезал (полный лог пишется в файле test-all-on.lua.out рядом со скриптом):
12/19/12 09:35:52 OnInit:2584
12/19/12 09:35:52 main start:2592
12/19/12 09:36:25 OnConnected:2584
12/19/12 09:36:25 OnParam:2584
12/19/12 09:36:25 OnParam:2584
12/19/12 09:36:25 OnQuote:2584
12/19/12 09:36:25 OnQuote:2584
12/19/12 09:36:25 OnDepoLimit:2584
12/19/12 09:36:25 OnDepoLimit:2584
12/19/12 09:36:26 OnParam:2584
12/19/12 09:36:32 OnQuote:2584
12/19/12 09:36:33 OnParam:2584
12/19/12 09:36:38 OnFuturesLimitChange:2584
12/19/12 09:36:39 OnParam:2584
12/19/12 09:36:40 OnParam:2584
12/19/12 09:36:38 OnFuturesLimitChange:2584
12/19/12 09:36:40 OnParam:2584
12/19/12 09:37:23 OnQuote:2584
12/19/12 09:37:30 OnParam:2584
12/19/12 09:37:30 OnTrade:2584
12/19/12 09:37:30 OnOrder:2584
12/19/12 09:37:30 OnDepoLimit:2584
12/19/12 09:37:31 OnParam:2584
12/19/12 09:38:33 OnAllTrade:2584
12/19/12 09:38:33 OnAllTrade:2584
12/19/12 09:38:33 OnAllTrade:2584
12/19/12 09:38:36 OnAllTrade:2584
12/19/12 09:38:57 OnParam:2584
12/19/12 09:38:58 OnParam:2584
12/19/12 09:39:02 OnStop:2584
12/19/12 09:39:02 main stop:2592
Из него и нарисовалась [url=https://quik2dde.ru/viewtopic.php?id=16]картинка в соседней теме "Как устроено Lua в QUIK[/url], правда к моменту ее написания все обработчики я еще не посмотрел.
Увы, к большому сожалению, документация и свежие сообщения на форуме от разработчиков в данном случае нас не обманывали: в отдельном потоке (с отличающимся ID потока) выполняется только функция main(), все остальные обработчики (во всяком случае все, вызов которых удалось увидеть) вызываются в рамках одного (основного) потока терминала QUIK. При этом при каждом запуске даже одного и того же скрипта ID потока в main() каждый раз разный, значит при каждом запуске создается новый поток OC Windows. Для других обработчиков ID потока остается неизменным, т.е. используется один и то же основной поток QUIK.
Обещанные в начале исходники:
[url=https://quik2dde.ru/static-img/100/test-all-on.zip]Полный скрипт и готовая DLL-ка в архиве[/url].