swerg написал: но QUIK совершенно без задержек реагирует
Дайте угадаю, в мейне есть вызов какой-то сишной функции? Так-то, если в нем один луа-цикл без никто, мейн лок захватит и все, квик на первом же колбеке встанет колом, о чем тут и сообщают.
Что такое минимальные задержки, это каждый понимал по-своему ) ну, ежли задача стоит показать, как "квик тормозит в сравнении с метатрейдером", то верной дорогой пойдено.
Anton написал: Дайте угадаю, в мейне есть вызов какой-то сишной функции? Так-то, если в нем один луа-цикл без никто, мейн лок захватит и все, квик на первом же колбеке встанет колом, о чем тут и сообщают.
Не надо ничего угадывать. Я взял буквально тот скрипт, который здесь был приведён. Вот полный текст:
Код
function OnStop ()
is_run = false
end
function main ()
is_run = true
a = 0
while is_run do
a = a + 1
end
end
Что такое минимальные задержки, это каждый понимал по-своему ) ну, ежли задача стоит показать, как "квик тормозит в сравнении с метатрейдером", то верной дорогой пойдено.
При чем тут задача показать как "квик тормозит в сравнении с метатрейдером"?
Я реально торгую на Е-Б-С счете через квик, Выводил данные через DDE в свое приложение (работало очень медленно), поэтому я и решил брать данные из МТ5 Стало гораздо быстрее...
Два Квика каких-то версий, несколько раз обновлённых, а какая там версия Lua - ваще без понятия, где её смотреть. О, в "компонентах" какая-то qlua.dll 3.0.3.2 - это, штоле? И мне абсолютно пофиг, подвесит этот пример мою ласточку или нет. Торгует (тьфу-тьфу, в обоих Квиках успешно) - и слава Богу!
Anton написал: Очень прожорливо из колбеков бродкасты отправлять. Оно ж буквально все окна в системе обходит в каждом колбеке.
Прожорливо, если используется 1 робот. Я использую 42 робота. Гораздо прожорливее будет запускать в Квике 42 скрипта да еще заморачиваться, чтобы указать handle принимающего приложения (как это реализовано в экспорте в МТ5,но там все просто) Потом PostMessage() тем и хорош, что он не ждет ответа - отослал и "забыл" о ней, а все 42 робота получат данные. "Прожорливо", так это с какой стороны смотреть :)
СОРОК ДВА РОБОТА?! Куда уж прожорливее - хоть с какой стороны смотреть. У меня как-то и один скрипт справляется. Думаю, как и у всех нормальных людей. Ресурсов практически не жрёт - ему же не надо рассылать данные по 42 направлениям.
Владимир написал: СОРОК ДВА РОБОТА?! Куда уж прожорливее - хоть с какой стороны смотреть. У меня как-то и один скрипт справляется. Думаю, как и у всех нормальных людей. Ресурсов практически не жрёт - ему же не надо рассылать данные по 42 направлениям. ::
"Нормальных" людей? Вы себя к ним опрометчиво причислили. Кстати, у меня на ФОРТС, работают 2 терминала МТ5, в сумме 86 роботов, и ничего не виснет...
Я когда-то работал техническим директором компьютерной фирмы. Так за "86 роботов" я бы уволил любого своего программера, ни секунды не задумываясь! Ах, какая прелесть: "не виснет"!
Ну это как-то в лоб решение. Клиенты могут раз в секунду, скажем, рассылать бродкаст WM_APP_QUIK_CLIENT_CONNECT (название условное) с хэндлом своего окна в wparam, скрипт (один) в квике их слушает, сохраняет хэндл клиента в список подписантов и отвечает WM_APP_QUIK_SERVER_CONNECT со своим хэндлом. И все, клиент прекращает спамить, а сервер в колбеках шлет PostMessage по списку. Ну то есть стырить идею в том же дде, чуть поправив.
Ну это как-то в лоб решение. Клиенты могут раз в секунду, скажем, рассылать бродкаст WM_APP_QUIK_CLIENT_CONNECT (название условное) с хэндлом своего окна в wparam, скрипт (один) в квике их слушает, сохраняет хэндл клиента в список подписантов и отвечает WM_APP_QUIK_SERVER_CONNECT со своим хэндлом. И все, клиент прекращает спамить, а сервер в колбеках шлет PostMessage по списку. Ну то есть стырить идею в том же дде, чуть поправив.
X-mmm. Вы сами-то торгуете несколькими роботами? Сделки от разных роботов совершаются достаточно часто, а средства для всех роботов одни. Перед сделкой роботы проверяют достаточность средств на счете для совершения оных. Поэтому каждый робот должен "мгновенно" получать инфу о состоянии счете (наличие свободных средств)
Он и будет получать настолько же "мгновенно", как и в случае бродкаста, не заваливая всю систему кучами бесполезных сообщений. Перечитайте еще раз, "раз в секунду" это процесс обнаружения клиента, как только он обнаружен, сообщения посылаются ему немедленно из колбеков. Если думаете, что пройтись по своему списку окон медленнее, чем винда пройдется по списку всех окон, то это заблуждение.
Клиенты не обязаны быть именно роботами и именно торговать. Кто-то статистику ведет, кто-то какие-то события отслеживает, упихивать все это разнородье в один процесс глупо как-то. Так что сама постановка вопроса "один квик - кучка подписантов" вполне себе нормальная. Есть еще вариант "кучка квиков - кучка подписантов".
Он и будет получать настолько же "мгновенно", как и в случае бродкаста, не заваливая всю систему кучами бесполезных сообщений. Перечитайте еще раз, "раз в секунду" это процесс обнаружения клиента, как только он обнаружен, сообщения посылаются ему немедленно из колбеков. Если думаете, что пройтись по своему списку окон медленнее, чем винда пройдется по списку всех окон, то это заблуждение.
Антон! То, что Вы предлагаете - очень здорово, но как мой скрипт (LUA) будет принимать сообщения от клиентов?
Anton, У меня нормальная постановка вопроса "один квик - один брокер". Мало того: один Квик - один счёт. Или, как минимум, один код клиента. Вести же статистику или события отслеживать одним процессом проблемы не представляет. По крайней мере, это в 100500 раз меньшие проблемы, чем использовать для этого "86 роботов".
На 64 битах HWND это void *, WPARAM и LPARAM - uintptr_t и intptr_t соответственно. Тут их режут до 32 бит и потом еще в даблы упихивают. Так что с использованием w32 я, видимо, ничего набрасывать не стану, во избежание последующих глюков, лучше тогда сразу в своей длл все и делать.
В мейне создаем невидимое окно hwndServer и затем обычный цикл сообщений. В оконной процедуре как-то типа
Код
switch(msg)
{
case WM_QUIK_CLIENT_CONNECT:
if(connections_allowed)
{
HWND hwndClient = (HWND)wparam;
client_list.push_back(hwndClient);
SendMessage(hwndClient, WM_QUIK_SERVER_CONNECT, (WPARAM)hwndServer, 0);
}
return 0;
case WM_QUIK_SERVER_STOP:
connections_allowed = false;
foreach(hwndClient in client_list)
SendMessage(hwndClient, WM_QUIK_SERVER_DISCONNECT, (WPARAM)hwndServer, 0);
client_list.clear();
DestroyWindow(hwndServer);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
// и так далее
}
В колбеках проходим по списку client_list и каждому hwndClient из него PostMessage(hwndClient, ...), точно так же, как в оригинале, только не бродкаст. В OnStop PostMessage(hwndServer, WM_QUIK_SERVER_STOP, 0, 0); Вроде и вся механика, помнить только о разных потоках для мейна и колбеков.
Спасибо, Антон! Только нельзя использовать SendMessage(), т.к она ожидает ответа. Странно, что PeekMessage не будет работать, PostMessage() работатет исправно. И еще... Думается, что так как я написал в разы проще будет... :)
Он и будет получать настолько же "мгновенно", как и в случае бродкаста, не заваливая всю систему кучами бесполезных сообщений. Перечитайте еще раз, "раз в секунду" это процесс обнаружения клиента, как только он обнаружен, сообщения посылаются ему немедленно из колбеков. Если думаете, что пройтись по своему списку окон медленнее, чем винда пройдется по списку всех окон, то это заблуждение.
Anton написал: Я тоже сейчас посмотрел внутрь (скачал сорцы у swerg) и есть подозрения, что работать эти функции не будут через w32. Например, PeekMessage
Код
long lwnd = MYP2HCAST luaL_optinteger( L, 1 , 0 ); // раз косяк
lua_pushnumber( L, ( long) msg.hwnd); // два косяк
lua_pushnumber( L, msg.wParam); // три косяк
lua_pushnumber( L, msg.lParam); // четыре косяк
На 64 битах HWND это void *, WPARAM и LPARAM - uintptr_t и intptr_t соответственно. Тут их режут до 32 бит и потом еще в даблы упихивают.
Часть функций после появления Int64 для Lua в QUIK я поправил (PostMessage, SendMessage), функции типа PeekMessage мне не нужны, их и не правил пока.
Ноги у либы растут из Lua 5.1 и x86, очевидно, и видимо автору хватало lua_number (который, как известно, в зависимости от сборки Lua может быть int или double; в QUIK это было double). Для Lua5.1 на x64 в этих функциях по уму надо был переходить на user data, чтобы не терять ничего, но после появления нормального int64 в Lua5.3 в QUIK надобность в этих извращениях, по счастью, отпала.