Известно, что функция main и колбэки (напр. OnTransReply) выполняются в разных потоках. Далее к проекту подключена с++ либа и функции из нее вызываются как и из функции main так и из колбэков. Далее, я понимаю механику следующим образом: - Функция main и колбэки отправляют в с++ либу разные lua_state, и поэтому в данном случае обращение к ним из либы в принципе не может пересечься поэтому потокобезопасно. - А вот разные колбэки сами по себе отправляют в либу одно и тоже lua_state и поэтому работа с ними в либе уже требует синхронизации.
Anton написал: Нет, в каждый момент времени выполняется только один колбек, между собой они никак не пересекутся, только с мейном.
Но ведь стейты разные же...и обращение к ним в любой момент времени не должно повлиять друг на друга...или все же разные стейты связаны друг с другом? К чему спрашиваю? Нужно ли как-то мне мэин и колбэк стеки вызовов синхронизировать или qlua.dll все уже сделала за меня? Допустим на одном тике я в колбэк отправлю push_integer, а на следующем уже в колбэк также отправлю push_string. Не вызовет ли это неопределенного поведения?
Виталий написал: Допустим на одном тике я в колбэк отправлю push_integer, а на следующем уже в колбэк также отправлю push_string. Не вызовет ли это неопределенного поведения?
Поправка Допустим на одном тике я в меин отправлю push_integer, а на следующем уже в колбэк также отправлю push_string. Не вызовет ли это неопределенного поведения?
Виталий написал: Но ведь стейты разные же...и обращение к ним в любой момент времени не должно повлиять друг на друга
Смотрите, пусть у вас в длл есть сишный колбек OnAllTrade(lua_State * s). Квик его вызывает в потоке колбеков, передает стейт колбеков, на вершине стека лежит ссылка на таблицу с данными. При этом перед вызовом вашей сишной функции луа отпустил лок. Пока вы не вернетесь из колбека, никто этот стек трогать не будет, ссылка так и лежит на вершине. В этом смысле да, стейты разные, стеки разные, в пределах потока со стеком можно делать что угодно и считать, что он, пока вы не вернулись из вызова, только ваш. В том числе можно смело lua_pushinteger и прочая. А вот таблица, на которую ссылка указывает, она не ваша, ссылка на нее может быть и у другого потока, и тот тоже может с ней что-то делать в данный момент. Вот здесь вам надо синхронизировать доступ.
Виталий написал: Но ведь стейты разные же...и обращение к ним в любой момент времени не должно повлиять друг на друга
Смотрите, пусть у вас в длл есть сишный колбек OnAllTrade(lua_State * s). Квик его вызывает в потоке колбеков, передает стейт колбеков, на вершине стека лежит ссылка на таблицу с данными. При этом перед вызовом вашей сишной функции луа отпустил лок . Пока вы не вернетесь из колбека, никто этот стек трогать не будет, ссылка так и лежит на вершине. В этом смысле да, стейты разные, стеки разные, в пределах потока со стеком можно делать что угодно и считать, что он, пока вы не вернулись из вызова, только ваш. В том числе можно смело lua_pushinteger и прочая. А вот таблица , на которую ссылка указывает, она не ваша, ссылка на нее может быть и у другого потока, и тот тоже может с ней что-то делать в данный момент. Вот здесь вам надо синхронизировать доступ.
Виталий написал: Известно, что функция main и колбэки (напр. OnTransReply) выполняются в разных потоках. Далее к проекту подключена с++ либа и функции из нее вызываются как и из функции main так и из колбэков. Далее, я понимаю механику следующим образом: - Функция main и колбэки отправляют в с++ либу разные lua_state, и поэтому в данном случае обращение к ним из либы в принципе не может пересечься поэтому потокобезопасно. - А вот разные колбэки сами по себе отправляют в либу одно и тоже lua_state и поэтому работа с ними в либе уже требует синхронизации.
Правильно ли я понял механизм?
Проблема синхронизации потоков не связана с исполняемым кодом, а связана с записью данных . -------------------- Из своего опыта: Особенностью работы с биржевыми данными является то, что всегда можно организовать данные так, чтобы запись в конкретный массив (вектор) делалась лишь одним потоком, а читались данные всеми другими. Так как данные поступают асинхронно, то в такой реализации синхронизировать ничего не надо. Проблем не возникает.
В итоге каждый колбек пишет принимаемые им данные в свой массив А функция main лишь читает эти данные. Синхронизировать колбек и main нет надобности, так как если колбек изменил данные, то main на следующем цикле их увидет.
nikolz написал: В итоге каждый колбек пишет принимаемые им данные в свой массив А функция main лишь читает эти данные. Синхронизировать колбек и main нет надобности, так как если колбек изменил данные, то main на следующем цикле их увидет.
У меня меин в блокировке ждет данных периодических...в этот момент колбеки вызывают функциии другие. Но стек то получается один и надо его синхронизировать.
Обратите внимание, назвал аргументы по-разному, отразив факт, что эти две функции получают разные стейты и, соответственно, разные стеки. Как вы описываете, мейн ждет некого события, потом что-то делает с полученными данными. Пусть мы хотим передать в мейн таблицу, полученную в OnAllTrade. Мы не можем просто взять и lua_xmove ее на стек мейна, потому что мейн в другом потоке выполняется и мы ему просто стек сломаем таким образом. Мы можем действовать по-разному. Во-первых, можем сделать чисто сишную потокобезопасную очередь с событием, распаковать таблицу в OnAllTrade в сишную структуру и сунуть в эту очередь, что разбудит мейн и он что-то там с этой таблицей сделает. Во-вторых, мы можем завести глобальную луа-таблицу в качестве очереди, в OnAllTrade совать туда таблицу и будить мейн, в мейне доставать таблицу и что-то с ней делать. Опять же надо прогарантировать, что мы работаем с таблицей потокобезопасно. В-третьих, мы можем в OnAllTrade просто будить мейн, игнорируя переданную таблицу, а в мейне вынимать все еще не обработанные записи прямо из ТВС циклом с getItem или даже одним SearchItems. В-четвертых, мы можем заякорить таблицу в OnAllTrade с помощью luaL_ref и передать в мейн только индекс в реестре, а в мейне вытащить таблицу из реестра, обработать и luaL_unref ее, чтобы коллектор мог ее потом собрать. Возможны еще варианты, если подумать. Как видите, все варианты предполагают некую синхронизацию.
Да, теперь пример тот, что я и имел в виду. Я, кстати, сразу сделал потокобезопасную очередь. Смущало лишь, что стеки стейтов могут друг на друга наложиться. Оказалось, что нормально все - на форуме нашел ссылку на документацию. Благодарю за разъяснения!
nikolz написал: В итоге каждый колбек пишет принимаемые им данные в свой массив А функция main лишь читает эти данные. Синхронизировать колбек и main нет надобности, так как если колбек изменил данные, то main на следующем цикле их увидет.
У меня меин в блокировке ждет данных периодических...в этот момент колбеки вызывают функциии другие. Но стек то получается один и надо его синхронизировать.
я решил проблему через системные события и мапинг файлы. В результате я могу данные из колбеков использовать в любых других скриптах т е потоках а не только в main данного скрипта. Чтобы стеки не пересекались определяю все данные как локальные для соответствующего потока.
А я решил проблему через использование ОДНОГО скрипта на все случаи жизни и минимально необходимого количества коллбеков (по сути, один только OnTrade, да обработчики событий от юзера). Чуть не половина веток этого форума посвящена этим несчастным потокам. Между тем форум посвящён организации автоматической торговли с помощью терминала QUIK, да ещё и на языке Lua. То бишь простенькой прикладной задаче. Не занимайтесь хернёй, господа! Ах, да - а вторая половина веток посвящена ловле этих несчастных миллисекунд - ещё одна разновидность онанизма.
Владимир, а я решал проблемы, когда в квике не было никакого луа вообще и транзакции загонялись через файлы. Вы еще не знаете, видимо, что вытворяли, чтобы в квик залезть в те времена, вот это был онанизм, а то что здесь - это именно программирование на луа, внешние длл по дизайну предусмотрены.
Anton, Я догадываюсь - я же не первый год программирую. Но сути это не меняет: это по-прежнему простенькая прикладная задача и по-прежнему с поганым языком и поганым интерфейсом. Но функциональность по-прежнему ДОСТАТОЧНАЯ для организации торговли. Что до "внешних длл по дизайну" - а зачем они нужны? Дизайн на таблицах Квика и всяких там SetTableNotificationCallback более, чем удовлетворительный - хрен такой получишь от этих внешних длл! А роботу, по большому счёту, это вообще не нужно. Только вот со свечами какой-то тихий ужас творится.
Владимир написал: Anton, Я догадываюсь - я же не первый год программирую. :: Но сути это не меняет: это по-прежнему простенькая прикладная задача и по-прежнему с поганым языком и поганым интерфейсом. Но функциональность по-прежнему ДОСТАТОЧНАЯ для организации торговли. Что до "внешних длл по дизайну" - а зачем они нужны? Дизайн на таблицах Квика и всяких там SetTableNotificationCallback более, чем удовлетворительный - хрен такой получишь от этих внешних длл! А роботу, по большому счёту, это вообще не нужно. Только вот со свечами какой-то тихий ужас творится.
Я Вам уже предлагал выше. Напишите конкретно что у вас за ужас со свечами. (проще задачи не бывает) Я Вам расскажу как решить Ваш ужас.
nikolz, Лапуль, Ваша информационная ценность для меня просто РАВНА нулю. Ну, расскажите, коль неймётся, как Вы будете получать дневные, недельные и месячные свечи - посмеёмся...
Владимир написал: Но функциональность по-прежнему ДОСТАТОЧНАЯ для организации торговли.
С этим не спорю. Свои боты тоже, хоть и внешние, довольно простые. Можно сказать, исторически сложилось, давно-давно в квике мало что можно было сделать. Потом, кроме торговли есть и другие задачи. Скажем, квик может служить источником твс для накопления, пресловутые свечи просто строю на лету из тиков. Все ж периодически надо что-то по истории посчитать. Накопление можно было бы и на луа сделать, но раз уже есть сишное, чего ж выдумывать-то. Кому-то кровь из носу охота смс получать с отчетами. Так что задачи есть, которые проще на сях порешать.
А так иногда стало возникать желание встроить в аппу луа и закодить бизнес-логику на нем, типа работает и радуйтесь, а что внутри какая вам разница. Но это вроде как некрасиво, люди на сишника тратились, а получат пыхыпы в обертке.
Anton, Что такое твс? Тепловыделяющая сборка? Трансформатор выходной строчный? Трансмиссивная венерическая саркома?
Ну ведь это МАРАЗМ строить свечи на лету из тиков! Гонять огромные объёмы данных на каждого клиента, и на каждом из них (хорошо, если одинаково!) получать из этих данных другие, меньшие по объёму на несколько порядков! А если обрыв связи? А если я уеду на рыбалку дня на три, и комп не возьму с собой? А получать свечи из графиков - это я даже не знаю, как назвать - даже матерные слова здесь слабоваты. У меня, блин, полторы тысячи тикеров на контроле, у каждого полтора десятка таймфреймов. И чо делать? Наконец, классические мат.ожидание и дисперсия в тыщу раз информативнее всей этой дурацкой "японистости".
Я тоже строю свои свечи, но не из тиков, а просто опрашиваю ТТТ (LAST) раз в полторы секунды. Лог у меня тоже ведётся, и никакие СМС нафиг не нужны. Да и просто свихнёшься: у меня обычно несколько десятков сделок в сутки - иногда больше, иногда меньше, и всей этой колодой бомбардировать мой телефон - упаси, Господи!
Я согласен: если что-то уже есть, чего ж выдумывать-то. Но вот "сишное" - это потенциальные проблемы по определению. Мне вот решительно всё равно, какие там версии Квика и языка - на всех работает. При этом, повторюсь, С мой любимейший язык на протяжении десятилетий, а на Луа я долго плевался, но даже тогда считал, что писать нужно на нём и только на нём.
Раньше таблица обезличенных сделок называлась таблицей всех сделок, ТВС. Так и называю до сих пор, потом вспоминаю, что уже не так называется.
Цитата
Владимир написал: Гонять огромные объёмы данных на каждого клиента, и на каждом из них (хорошо, если одинаково!) получать из этих данных другие, меньшие по объёму на несколько порядков! А если обрыв связи?
Все клиенты локальные, далеко гонять не надо. Есть квик и другие источники, они в реальном времени или задним числом, если что-то пропущено, наполняют базу тиков, есть сервер данных, любая желающая аппа цепляется к нему и получает тики сплошным потоком "вот с этой даты" и { "по эту дату" или "в реальном времени" }. В большинстве случаев никакие свечи вообще не строятся, голый тиковый поток используется как есть, но если порисовать чего, то просто на лету в свечки. Объем не так и велик, одна сессия ужимается в десяток мегов, распаковка уже самой клиентской аппой тоже на лету. Часть сжатия там тксть ноухау, поверх него - deflate, как бы одна из причин, почему на луа переделывать - только приключений искать.
Цитата
Владимир написал: Да и просто свихнёшься: у меня обычно несколько десятков сделок в сутки - иногда больше, иногда меньше, и всей этой колодой бомбардировать мой телефон - упаси, Господи!
Одно время сделал уведомления о сделках тем самым голосом, что в автопилотах вещает. Быстро убрал, задрало насмерть. Но на посетителей производило неизгладимое впечатление. Мечта ж, бот жужжит, бабло бежит, еще и силиконовая баба бесстрастно докладает о прибылЯх несметных.
Владимир написал: nikolz, Лапуль, Ваша информационная ценность для меня просто РАВНА нулю. Ну, расскажите, коль неймётся, как Вы будете получать дневные, недельные и месячные свечи - посмеёмся...
Владимир, Вообще-то это Вы льете крокодильи слезы про ужас со свечами. У меня нет проблем Не хотите помощи, нет проблем. Полагаю Вам надо лишь ля-ля. Успехов в словесном поносе на форуме.
Anton, Какие такие "все клиенты локальные"?! Тики идут с сервера, а свечи считаются на каждом клиенте. У меня просто челюсть отвисла, когда я об этом узнал. Кому и на кой нужна эта "база тиков"? Разве что этому дурацкому HFT, а нормальные решения по ним принимать практически невозможно - нужны именно свечи. И при чём тут "порисовать"? Мне вот нужно порядка 12 000 свечей (от 15-минутных до месячных - мелочь я считаю сам), и объём у них не "ужатых десяток мегов", да ещё ноухавно ужатых, а распакованных сотня кило. И никаких графиков! Получать к ним доступ через графики - это даже не "только приключений искать", а Полная Жопа!
nikolz, Лапуль, ежу понятно, что "у Вас нет проблем" - Вы же НИЧЕГО не умеете! Какая, в задницу, могёт быть "помощь" от распальцованного полуграмотного неуча, которому я ещё 16.10.2020 08:43:39 писал: "Учите матчасть"? А 30.10.2020 13:46:16 писал: "Открываем книжицу "Руководство пользователя" от ARQA - так там буквально в названии чёрным по белому: "ИНТЕРПРЕТАТОР языка Lua". VM, да будет Вам известно, это ТОЖЕ интерпретатор! А 31.10.2020 12:35:26 писал: "Может, хватит, господа? Сначала один нёс какую-то клиническую ахинею про "роботов и всякие прочие глупости", да ещё с гнутыми пальцами вроде "вы даже понимаете суть вопроса". Получил щелчок по носу - теперь чего-то шипит про "троллей". Потом второй начал пальцы гнуть на тему API в том же ключе: "По-моему вы ничего не понимаете", да про int-float ("Как бы по мягче сказать, что вы не разбираетесь в теме. Повторю в квике 7, lua 5.1 - в нем не числа хранятся типом double, соответственно нельзя хранить int64"), да про "не надо путать стек процессора и стек Lua - это разные стеки. Вам бы документацию почитать и хорошенько разобраться в луа", да про "выучи английский", да про "умение читать документацию и гуглить", после чего вообще забился в истерике. Потом третий понёс пургу про "монстров фондового рынка", и тоже с гнутыми пальцами: "Вы еще далеки от понимания реальности фондовых рынков" и совсем уж клинический бред с ещё большей распальцовкой: "вот некоторые из аксиом, которые надо усвоить и научится программировать", затем бред про мантиссы ("для справки: Разрядность мантиссы в 64 битном вещественном числе составляет 52 бита, что позволяет точно отобразить лишь 16 разрядное десятичное целое число, а не 18 квинтиллионов, как наивно полагает Владимир"), затем про "это VM а не интерпретатор", и тоже с истерикой: " в языках и виртуальных машинах вы ноль без палочки"... я прям утомился этому неучу по носу щёлкать!" Если забыли, то "третий" - это как раз Вы, лапуль.
В общем, надоело листать: Последнее, что попалось на глаза из моих обращений к Вам, датировано 04.08.2021 13:57:04: "Что, сегодня в Кащенко день открытых дверей?". Да 16.08.2021 12:47:16: "Лапуль, ну хватит напрашиваться! Ну ведь растопчу и проглочу, как это уже не раз бывало. У нас просто разные весовые категории".
Владимир написал: Тики идут с сервера, а свечи считаются на каждом клиенте. У меня просто челюсть отвисла, когда я об этом узнал.
Вы о квике? Свечи едут на клиент с сервера готовые, насколько мне известно.
Цитата
Владимир написал: Какие такие "все клиенты локальные"?!
Мои аппы - клиенты моего сервера. Локальные клиенты локального сервера. И их, естественно, не тысячи, на каждом из трех-пяти это не то, о чем переживать стоит.
Цитата
Владимир написал: Кому и на кой нужна эта "база тиков"? Разве что этому дурацкому HFT
Из тиков можно построить любые агрегаты. Из свечей можно построить только свечи кратного фрейма. Очевидно же, что надо хранить.
Цитата
Владимир написал: нормальные решения по ним принимать практически невозможно - нужны именно свечи.
Я б поспорил, напомнил бы теорему Котельникова, прикинул бы, какова частота найквиста для минутных, скажем, свечек, и какова частота тиков, из которых эти минутные строятся, спросил бы, куда деваются частоты выше найквиста, ответил бы, что отражаются в низкочастотную часть, прикинул бы амплитуды разных частот, обнаружил бы, что отраженная составляющая может быть больше истинно низкочастотной, заявил бы, что в свечах появились составляющие, которых не было в исходных тиках, что ж мы анализируем тогда, артефакты дискретизации? Но не буду )
Anton, Я о Квике. У меня никогда не было ни малейших сомнений, что свечи считаются на сервере, но, как мне тут популярно объяснили, считаются они на клиенте из таблицы обезличенных сделок.
Из тиков МОЖНО построить любые агрегаты. Ну так и стройте их НА СЕРВЕРЕ! А на клиента транслируйте уже готовые "агрегаты". И на сеть нагрузка будет намного меньше, и процессоры клиентские не придётся забивать дурацкой работой.
А здесь и спорить нечего: нормальные решения по тикам принимать практически невозможно - нужны именно свечи. Аксиома!
Владимир, а можно ссылку на то кто вам "популярно объяснил" про расчет свечей на клиенте? Просто звучит как что-то неразумное. Всегда считал, что свечи с сервера получаем.
Помогают ли свечи от геморроя? в общем да, но вот когда догорают... Ок, возьмем свечу и будем двигать ее вправо тик за тиком. Некоторые называют это скользящим окном.
Anton, Нет уж, ничего скользящего - только прыгающее. Пока очередная свеча не накоплена, смотрим на предыдущую. Тогда, возможно, помогут и от геморроя.
Владимир, хозяин барин. Чет вот вспомнил. Был интересный чел, математик кстати, обнаруживший вырождение распределения в многочастичном фильтре, принявший эффект за имманентное свойство рынка и, что забавно, поднявший на этом неплохо бабла. Где-то в 14 году вышла работа об этом эффекте, доказывающая, что он есть свойство самого фильтра. К сожалению, с челом уже нельзя пообщаться на эту тему по объективной причине, а было бы интересно его мнение теперь услышать. Это я к чему. Все йогурты могут быть полезны, пока горят достаточно далеко от.
Здравствуйте. Кто может подсказать как идет поток ордеров в таблице обезличенных сделок, например одномоментно в 10:10:00 прошло 7 продаж (7 строк) 20 контрактов, 18, 15, 10 и 5. Эти 7 строк в ленте отображаются разом или каждая строчка по отдельности только очень быстро?
Коc написал: Здравствуйте. Кто может подсказать как идет поток ордеров в таблице обезличенных сделок, например одномоментно в 10:10:00 прошло 7 продаж (7 строк) 20 контрактов, 18, 15, 10 и 5. Эти 7 строк в ленте отображаются разом или каждая строчка по отдельности только очень быстро?
присылают блоком вот поэтому видите разом но с разным временем. количество в блоке зависит от интенсивности торгов. ----------------------- исследовать реальную задержку можно сравнивая время сделок с временем сервера точного времени. Попробуйте и увидите много интересного.
nikolz написал: присылают блоком вот поэтому видите разом но с разным временем.
Спасибо nikolz. Уточнить, присылают одним блоком, а время будет например 10:10:00 и 10:10:03 (разница 3 секунды). Т.е. ордера с временем 10:10:03 как бы отношения к предыдущим ордерам с временем 10:10:00 не имеют? Почему так сделано интересно, просто захотелось или есть какая то техническая сложность в этом.
Сделки приедут с той временной меткой, в которую случились. Но, естественно, приедут чуть позже этого времени. В нормальных условиях о секундных задержках речь не идет, десятки миллисекунд, но в при плохом канале возможны и бОльшие задержки.
Сложность называется интернет. Чтобы отправить что-то по сети, это что-то всегда режется на куски и каждый кусок отправляется сам по себе, при этом к нему приделывается сначала заголовок протокола приложения, потом заголовок протокола сети, потом заголовок пакета, потом заголовок канального уровня. Если резать на слишком мелкие куски, по сети будут ездить туда-сюда одни лишь заголовки. Поэтому крайне желательно подсобрать данных перед отправкой, а не каждый байт посылать отдельно.
То, что колбэки могут приходить в разной последовательности(интересуют OnTrade, OnOrder, OnTransReply), а не в строго определённой это ещё ладно. Но вот было замечено, что работа одного колбэка может запросто прерываться, может начать выполняться другой колбэк или функция, вызываемая из main. Всё это приводит к тому, что в консоли получается каша из принтов от разных функций и колбэков. Сначла решил просто выводить принты от разных колбэков разным цветом в консоль- типа хоть как-то видно будет какой принт от кого, хоть и перемешаны они в консоли. Потом решил сделать так, чтобы пока не выполнится один колбэк полностью, другой колбэк не мог бы выводить принты в консоль. Внутри каждого колбэка в начале - вход в критическую секцию, в конце - выход из секции. Т.е. логика такая. Зашёл в колбэк - он сделал вход в секцию. Потом этот колбэк прерывается и квик запускает другой колбэк, который тоже пытается зайти в секцию, но не может, ибо она захвачена другим колбэком уже, т.е. он зайти не может, ждёт, пока секцию освободит первый колбэк и только потом продолжит своё управление. Но...вопрос: а дождётся ли он освобождения пока ждёт? Сможет ли квик пока тот ждёт прервать выполнение второго ожидающего колбэка и продолжить выполнение первого? Если да, то всё ОК. Первый освободит секцию, второй потом захватит её, отработает и завершится. Но не понятно как организована работа в квике по обработке колбэков. Толи в одном потоке, толи в разных, толи как-то по времени умудряется. Если в разных то проблем нет. Один поток тормознётся, пока другой отработает. Запускал простейший скрипт - выставит заявку, снять заявку. Вроде всё срабатывает и не зависает. Но может это пока просто потому, что именно так складывается и при прерывании одного колбэка другой просто не вызывается, а если вызовется, то зависнет. Может сталкивался кто с подобным или подскажет как вызываются колбэки квиком? А то зависнуть может же при определённых условиях. Иными словами вопрос такой: заход в колбэк, колбэк пытается войти в критическую секцию, она занята, он тормозится, ждёт освобождения секции, квик прервёт этот колбэк и запустит исполнение другого колбэка или функции, которые освободят критическую секцию, или зависнет?
В скриптах используются всего 2 потока, один для колбэков и один в main.
В main для каждого скрипта создается отдельный поток, а вот колбэки находятся в некой очереди и вызываются синхронно, т.е. каждый колбэк ждет возвращения управления перед вызовом следующего.
Из-за этого имеем 2 особенности: 1. Нет нужды синхронизировать колбэки. 2. Надолго блокировать или производить тяжелые расчеты в колбэках не стоит, это приводит к подвисанию всех скриптов и даже терминала.
Станислав написал: В скриптах используются всего 2 потока , один для колбэков и один в main.
В main для каждого скрипта создается отдельный поток, а вот колбэки находятся в некой очереди и вызываются синхронно, т.е. каждый колбэк ждет возвращения управления перед вызовом следующего.
Из-за этого имеем 2 особенности: 1. Нет нужды синхронизировать колбэки. 2. Надолго блокировать или производить тяжелые расчеты в колбэках не стоит, это приводит к подвисанию всех скриптов и даже терминала.
Если я ошибаюсь, поправьте.
немного поправлю. Для колбеков не создается специально новый поток. Колбеки вызываются в VMLua, которая создается в основном потоке терминала QUIK. --------------------------- Функция main запускается в отдельном потоке, в котором создается VMLua, дочерняя к VMLua колбеков.
Станислав написал: В скриптах используются всего 2 потока , один для колбэков и один в main.
В main для каждого скрипта создается отдельный поток, а вот колбэки находятся в некой очереди и вызываются синхронно, т.е. каждый колбэк ждет возвращения управления перед вызовом следующего.
Из-за этого имеем 2 особенности: 1. Нет нужды синхронизировать колбэки. 2. Надолго блокировать или производить тяжелые расчеты в колбэках не стоит, это приводит к подвисанию всех скриптов и даже терминала.
Если я ошибаюсь, поправьте.
Да, потестирвал. Пришёл к такому же выводу. Колбэки вызываются последовательно все какие есть из всех запущенных скриптов. Синхронизация их между собой не нужна. main() и функции, которые она вызывает - это отдельный поток. Поток main() и поток колбэков синхронизирую между собой через критическую секцию в DLL. Сейчас всё отлично работает в пределах одного процесса. Далее сделаю либо через мьютексы для разных процессов, которые используют DLL, либо в DLL буду делать массив - открывать каждому процессу свою критическую секцию при подключении к DLL, чтобы каждый процесс использовал свою для своих потоков. И да, кто хочет так же использовать именно критические секции - не забывайте, что каждому процессу - своя секция и что сколько раз поток зашёл в секцию(а он может входить в неё последовательно подряд несколько раз без проблем), то столько же раз он должен потом из неё и выйти. У меня возникала странная ситуация - видимо когда вылетал по ошибке, не успел покинуть секцию поток колбэков, после этого при перезапуске скрипта функция из main() заходила и покидала секцию через вызов другой функции, потом в секцию заходил и покидал её поток колбэков и вот после этого поток main() уже зайти в секцию не мог. Звучит странно, ведь первый раз main() в секцию всё-таки заходил. При этом исключено, что поток колбэков где-то мог дополнительно не покинуть секцию. Понять долго не мог что не так работает. Тестировал и вставлял принты везде где только можно - везде вход - выход, а поток main() со второго раза зайти не может! После перезагрузки, когда нет вылетов всё заработало без проблем.
Станислав написал: В скриптах используются всего 2 потока , один для колбэков и один в main.
В main для каждого скрипта создается отдельный поток, а вот колбэки находятся в некой очереди и вызываются синхронно, т.е. каждый колбэк ждет возвращения управления перед вызовом следующего.
Из-за этого имеем 2 особенности: 1. Нет нужды синхронизировать колбэки. 2. Надолго блокировать или производить тяжелые расчеты в колбэках не стоит, это приводит к подвисанию всех скриптов и даже терминала.
Если я ошибаюсь, поправьте.
немного поправлю. Для колбеков не создается специально новый поток. Колбеки вызываются в VMLua, которая создается в основном потоке терминала QUIK. --------------------------- Функция main запускается в отдельном потоке, в котором создается VMLua, дочерняя к VMLua колбеков.
Да похоже как-то так и есть. Факт только один - надо синхронизировать поток main() с потоком колбэков, кто бы его не запускал. Можно конечно поюзать всякие процесс мониторы и т.п., посмотреть процессы и их потоки, но и так понятно по вызовам стало, что main() и колбэки живут в разных потоках и что колбэки вызываются последовательно. Всем спасибо за ответы.
Станислав написал: В скриптах используются всего 2 потока , один для колбэков и один в main.
В main для каждого скрипта создается отдельный поток, а вот колбэки находятся в некой очереди и вызываются синхронно, т.е. каждый колбэк ждет возвращения управления перед вызовом следующего.
Из-за этого имеем 2 особенности: 1. Нет нужды синхронизировать колбэки. 2. Надолго блокировать или производить тяжелые расчеты в колбэках не стоит, это приводит к подвисанию всех скриптов и даже терминала.
Если я ошибаюсь, поправьте.
немного поправлю. Для колбеков не создается специально новый поток. Колбеки вызываются в VMLua, которая создается в основном потоке терминала QUIK. --------------------------- Функция main запускается в отдельном потоке, в котором создается VMLua, дочерняя к VMLua колбеков.
Да похоже как-то так и есть. Факт только один - надо синхронизировать поток main() с потоком колбэков, кто бы его не запускал. Можно конечно поюзать всякие процесс мониторы и т.п., посмотреть процессы и их потоки, но и так понятно по вызовам стало, что main() и колбэки живут в разных потоках и что колбэки вызываются последовательно. Всем спасибо за ответы.
мьютексы излишне использовать, так как всего два потока. Ранее уже говорил, что это решается гораздо проще через Event. ------------------ Прикольно, что недавно реализовал работу этих потоков без элементов ОС синхронизации. Работает существенно быстрее даже относительно Event.
nikolz написал: мьютексы излишне использовать, так как всего два потока.Ранее уже говорил, что это решается гораздо проще через Event.
Если рассматривать вариант использования только одного экземпляра квика, то да. Но вот у меня, например, на данный момент рабочих целых 4 варианта самостоятельных квиков. Все они используют в работе всегда одну и ту же DLL, которая обеспечивает мне консоль для вывода, ну и разные функции для работы с этой консолью, в том числе и цветной вывод. Для цветного вывода хош-не хош нужна синхронизация, иначе всё идёт в перемешку, хоть и разным цветом, что очень неудобно воспринимать, хотя и можно смириться с этим, но я решил не мириться. Так вот, коли 4 квика, то по сути это уже и 4 разных процесса. И поэтому либо мьютекс нужен, либо быстрая критическая секция. Но секция одна на разные процессы не пойдёт. Я выбрал для себя в реализации именно секции, но приходится хранить массив из секций (для каждого потока своя секция), которые инициализируются при подключении процесса в DLL. Сейчас всё работает как положено. Ну пришлось чуток добавить кода, но оно того стоит думаю.
nikolz написал: Прикольно, что недавно реализовал работу этих потоков без элементов ОС синхронизации.Работает существенно быстрее даже относительно Event.