Если бы я был архитектором QUIK, Что стоило бы изменить в QUIK по-крупному
Пользователь
Сообщений: Регистрация: 12.05.2020
14.02.2026 10:16:21
Вопрос к поддержке: В QUIKе много различных коллбеков. Где гарантии, что они не пропускают события, по которым должны выполняться? Пропуск событий в заявленных коллбеках, даже если это происходит нечасто, это ошибка QUIK. В существующей версии QUIK коллбеки выполняются в единственном служебном потоке. Что происходит в QUIKе если возникает очередное новое событие, по которому должен выполниться коллбек и при этом не был обработан предыдущий? Есть служебные очереди необработанных событий? В существующей версии QUIK выполнение коллбека блокируется до тех пор пока в потоке main не выполнится sleep или сишная функция. Выше написанное означает полную зависимость служебного потока от пользовательского. Зачем это сделано в QUIKe? В этой ветке были изложены предложения, которые, по моему мнению, могли бы устранить описанные выше проблемы. Что в этих предложениях не понятно или вызывает сомнения?
Пользователь
Сообщений: Регистрация: 02.01.2026
14.02.2026 13:27:05
Цитата
TGB написал: В существующей версии QUIK выполнение коллбека блокируется до тех пор пока в потоке main не выполнится sleep или сишная функция. Выше написанное означает полную зависимость служебного потока от пользовательского. Зачем это сделано в QUIKe?
Блокируется на время выполнения байт-кода. Не представляю, какой код нужно написать без вызова сишных функций, выполняющийся длительное время, чтобы это можно было заметить.
Пользователь
Сообщений: Регистрация: 30.01.2015
14.02.2026 15:11:44
Функция sleep уступает свободное время потока следующему потоку. Например sleep(1000) в main означает, что поток main будет остановлен системой на 1000 ms. ----------------------- Таким образом, функция sleep выполняется быстро, так как ее задача сообщить ОС чтобы та разбудила поток через заданное время. ОC устанавливает таймер на событие "запустить поток main через 1000 ms. ------------------------ Все эти действия выполняются буквально мкс . Поэтому ничего не блокируется для исполнения sleep.
Пользователь
Сообщений: Регистрация: 30.01.2015
14.02.2026 15:13:41
чтобы остановить выполнение потоко с колбеком надо в функцию колбека поставить sleep. Поток колбека будет остановлен на время указанное в sleep.
Пользователь
Сообщений: Регистрация: 30.01.2015
14.02.2026 15:20:35
и еще... Если значение аргумента sleep равно нулю, поток освобождает оставшуюся часть своего интервала времени для любого потока с таким же приоритетом, готовым к выполнению. Если других готовых к выполнению потоков с таким же приоритетом нет, выполнение текущего потока не приостанавливается.
Пользователь
Сообщений: Регистрация: 12.05.2020
14.02.2026 18:29:42
Цитата
nikolz написал: Поэтому ничего не блокируется для исполнения sleep.
Когда же вы научитесь читать ? Вы читаете тексты перед тем как писать? Ведь написано:
Цитата
TGB написал: блокируется до тех пор пока в потоке main не выполнится sleep или сишная функция
Где вы видите у меня фразу: "для исполнения"? У вас какое то недержание ваших текстов.
написал: Поэтому ничего не блокируется для исполнения sleep.
Когда же вы научитесь читать :: ? Вы читаете тексты перед тем как писать? Ведь написано:
Цитата
написал: блокируется до тех пор пока в потоке main не выполнится sleep или сишная функция
Где вы видите у меня фразу: "для исполнения"? У вас какое то недержание ваших текстов.
Вы тоже не умеете читать. Что именно по-вашему блокируется "пока в потоке main не выполнится sleep" Напишите конкретно от какого до какого момента исполнения кода в функции Main блокируется -------------------- Я написал именно на это ваше высказывание. Ничего не блокируется "до тех пор пока в потоке main не выполнится sleep или сишная функция" =================== Поясняю специально для Вас: Поток может останавливается в многопоточной системе если он обращается к ПАМЯТИ ДАННЫХ , к которой обращается в данный момент другой поток. И то если потоки должны писать в эту память. Если они читатели то никакой блокировки никто не делает. --------------------------------------- Теперь скажите К КАКОЙ ПАМЯТИ ВСЕГДА одновременно обращаются колбек и поток main для записи данных в эту память "до тех пор пока в потоке main не выполнится sleep или сишная функция" --------------------------------------
Пользователь
Сообщений: Регистрация: 30.01.2015
15.02.2026 07:21:05
, Если Вы знаете русский язык, то фраза "до тех пор пока в потоке main не выполнится sleep или сишная функция" означает, что время измеряется от некоторого момента до выполнения sleep до момента окончания выполнения sleep. ----------------- И понять эту фразу очень сложно. Время до оператора sleep - это время обработки очереди в цикле в main (пример есть в документации). Если бы в это время колбеки остановились, то никакой очереди создать было бы невозможно. -------------------- момент времени после исполнения sleep Если в sleep 0, то это практически время начала исполнения sleep B этом случае оно совпадает с началом цикла обработки очереди. ----------------------------- таким образом Вы сказали буквально следующее: Колбеки всегда остановлены если в main нет функции sleep или параметр у нее равен нулю. Но колбеки прекрасно работают и без sleep в main. ---------------------------- Согласитесь, что вы сказали чушь.
Пользователь
Сообщений: Регистрация: 12.05.2020
15.02.2026 11:56:46
Цитата
nikolz написал: Что именно по-вашему блокируется "пока в потоке main не выполнится sleep" Напишите конкретно от какого до какого момента исполнения кода в функции Main блокируется
Вы опять не читаете или ничего не соображаете. У меня же написано конкретно то, что давно известно:
Цитата
TGB написал: В существующей версии QUIK выполнение коллбека блокируется до тех пор пока в потоке main не выполнится sleep или сишная функция.
Выполните в main строку: for i = 0, 10000000000 do end и вы заблокируете секунд на 30 не только коллбеки, но и диалог QUIK. -----
Цитата
nikolz написал: Вы сказали буквально следующее: Колбеки всегда остановлены если в main нет функции sleep или параметр у нее равен нулю.
Вы опять меня "передергиваете". Где я это писал буквально? Читайте мою приведенную выше цитату. Вы понимаете что означает слово буквально? Зачем вы меня "передергиваете" и пытаетесь приписать свои фантазии? Вы продолжаете работать прокладкой между комментариями ?
В указанный период на сервере проводились технические работы, которые и стали причиной невозможности снятия заявки через Рабочее место и средствами скриптов. Приносим свои извинения за доставленные неудобства.
Пользователь
Сообщений: Регистрация: 12.05.2020
19.02.2026 09:28:27
Цитата
Oleg Kuzembaev написал: В указанный период на сервере проводились технические работы, которые и стали причиной невозможности снятия заявки
Здравствуйте! Спасибо за ответ. У меня просьба к вам: донести до разработчиков мои комментарии 1, 51.
QUIK clients support
Сообщений: Регистрация: 11.08.2025
19.02.2026 10:00:57
Благодарим вас за обратную связь. Такая информация довольно ценна для улучшения продуктов от нашей компании.
В данном случае, нам видится возможность зарегистрировать пожелание на доработку будущих версий ПО. Однако необходимо достичь понимания, какая именно доработка требуется. Если у вас уже есть такая наготове, то просьба предметно описать ее: что именно стоит добавить? Как это будет выглядеть в вашем представлении? После сбора всей информации, мы с радостью зарегистрируем такое пожелание.
Пользователь
Сообщений: Регистрация: 12.05.2020
19.02.2026 13:06:40
Цитата
Oleg Kuzembaev написал: В данном случае, нам видится возможность зарегистрировать пожелание на доработку будущих версий ПО. Однако необходимо достичь понимания, какая именно доработка требуется.Если у вас уже есть такая наготове, то просьба предметно описать ее: что именно стоит добавить? Как это будет выглядеть в вашем представлении?
1. Я исхожу из того, что среди пользователей QUIK могут быть квалифицированные IT-разработчики, которые могут улучшить мои предложения и поэтому выкладываю их в публичку. 2. Сохранение существующего API QLua, с тем, чтобы обеспечить совместимость с существующими разработками пользователей, является основным ограничением на предлагаемое. ------------------- I. В текущей версии QUIK в одном основном потоке обслуживаются: - запуск всех Lua-скриптов пользователя; - запуск коллбеков всех Lua-скриптов пользователя; - обработка всех коллбеков таблиц QUIK (это не таблицы Lua); - обработка всех индикаторов пользователя. Притом, что в текущий момент у подавляющего количества ПК много ядер ЦП, написанное выше явный перебор. Наверное, нет проблем перечисленное выше обрабатывать в отдельных потоках, так как перечисленные выше функции, в моем представлении, не сильно связаны друг с другом и, на первый взгляд, между ними не требуется синхронизация.
II. Интерфейс взаимодействия QUIK c Lua-скриптом пользователя, реализованный в виде коллбеков, предполагает многопоточный режим использования Lua, порождающий неприятные проблемы параллельного программирования (для решения которых сами же разработчики предлагают использовать потокобезопасную очередь между коллбеками и потоком main). Мне представляется, что имеет смысл вместо коллбеков использовать активную очередь событий, При этом не требуется использовать Lua в многопоточном, редко используемом и не очень стабильном режиме. При этом не будет проблем с подключением новых версий Lua. Более того, скрипты пользователя будут выполняться несколько быстрее из-за отсутствия синхронизации, требуемой в многопоточном варианте использования Lua. Конкретные предложения: 1) Lua подключать в однопоточном режиме, нативном варианте, без внесения изменений в исходники. Все необходимые коды QLua перенести в dll-пакет. 2) Для взаимодействия со скриптами пользователя использовать общие для них служебные циклические очереди (в соответствии с существующими функциями обратного вызова). Длины очередей задавать по умолчанию с возможностью их изменения пользователем. Для каждого запускаемого скрипта пользователя создавать блоки доступа (с соответствующими указателями, обеспечивающими чтение очередей без блокировки) к общим циклически очередям. 3) Функции чтения очередей регистрировать под теми же именами и так же, как это делается для существующих коллбеков. 4) Выполнять функции чтения очередей в модифицированной следующим образом sleep: - sleep выполняется по истечению заданного в ней интервала времени или при получения сигнала поступления данных в одну из циклических очередей (в пропуске сигналов нет проблем, так есть запуск по времени); - выполнение функции начинается с анализа появления новых данных в циклических очередях скрипта (конкретного) и запуска зарегистрированных его функций с теми параметрами из очередей, как это делается в существующей версии QUIK; - в качестве результата в модифицированной sleep выдавать значения: количество считанных записей в очередях, признак отсутствия потерь данных в очередях из-за их переполнения (с указанием очередей, в которых это возникло), и, возможно, еще что-то. Предложенное: 1) устраняет зависимость служебного потока от пользовательского, когда (служебный) в существующей версии QUIK может быть блокирован пользовательским, а пользовательский служебным; 2) устраняет необходимость внесения правок в исходники Lua; при этом скрипты пользователя будут выполняться несколько быстрее из-за отсутствия синхронизации, требуемой в многопоточном варианте использования Lua; 3) обеспечивает контроль потерь данных в очередях, а также возможность исключения этих потерь за счет увеличения длин очередей пользователем или уменьшения времени ожидания в sleep; 4) убирает проблемы синхронизации внутри скрипта пользователя.
III. В QUIK реализована функциональность просмотра графика котировок бумаг QUIK. Но отсутствует возможность просмотра котировок бумаг, сохраненных во внешних файлах. С учетом существующей функциональности QUIK, как мне представляется, реализация этой возможности не потребует больших усилий.
IV. Пожелание: сократить время восстановления взаимодействия QUIK с сервером при перезапуске хотя бы до 10 сек.
Пользователь
Сообщений: Регистрация: 02.01.2026
19.02.2026 14:43:11
TGB, можете написать прсевдокод, как по-вашему, использовать очередь событий?
Пользователь
Сообщений: Регистрация: 12.05.2020
19.02.2026 15:46:21
Цитата
Йцукен написал: можете написать прсевдокод, как по-вашему, использовать очередь событий?
Я так понимаю, в случае реализации предложенного.
У пользователя никаких изменений:
Код
<Определение функций обработки событий ровно так, как это сейчас>
--- Весь код скрипта без изменений, в том числе sleep(<Интервал>) --
-- Отличие только в реализации функции sleep.
-- При ее вызове с заданным интервалом внутри нее выполняется (код на C++):
WaitForSingleObject(<ОбъектОжидания>, <Интервал>); // здесь ожидание истечения <Интервала> или выдачи сигнала QUIK (неблокирующей функцией Pulse в служебном потоке) о записи в очереди новых событий.
-- Когда sleep "срывается" с <ОбъектаОжидания>, то в ней анализируются очереди (это можно сделать эффективно, используя битовую шкалу непустых очередей скрипта) и выполняются соответствующие <Функций обработки событий> с параметрами считанными из очередей.
-- Функционально это не отличается от того, что реализовано сейчас, но выполняется в потоке пользователя main.
-- Тому, кому интересны детали выполнения sleep, может изменить в своем скрипте формат вызова sleep: вместо sleep(<Интервал>) строка
local <Количество обработанных элементов очереди>, <Данные о потерях событий в очередях> = sleep(<Интервал>)
Пользователь
Сообщений: Регистрация: 02.01.2026
19.02.2026 15:52:01
TGB, колбэки внутри sleep должны вызываться или как?
Пользователь
Сообщений: Регистрация: 12.05.2020
19.02.2026 16:00:27
Цитата
Йцукен написал: колбэки внутри sleep должны вызываться или как?
Да, так называемые коллбеки, должны вызываться внутри sleep (выполняемой в потоке main) с данными из очередей.
Пользователь
Сообщений: Регистрация: 02.01.2026
20.02.2026 10:03:39
TGB, а что делать, если между слипами данные поступили по инструменту несколько раз?
Пользователь
Сообщений: Регистрация: 12.05.2020
20.02.2026 11:01:47
Цитата
Йцукен написал: а что делать, если между слипами данные поступили по инструменту несколько раз?
При "просыпании" sleep, функции чтения очередей (коллбеки) будут выполняться (последовательно, без пропусков) столько раз сколько необработанных записей в очередях. Если очереди не переполняются, а это можно контролировать и не допускать, то события не теряются, но возможны задержки в их отработке. Как было указано ранее, sleep "просыпается" либо по времени, либо по записи в очереди данных из QUIK. Но при этом в в sleep всегда анализируются и при необходимости обрабатываются непустые служебные очереди скрипта.
Пользователь
Сообщений: Регистрация: 02.01.2026
20.02.2026 11:24:39
А смысл несколько раз подряд обрабатывать, например OnQuote, если каждый раз мы будем обрабатывать одни и те же данные? Или вы предлагаете хранить данные для каждого колбэка?
Пользователь
Сообщений: Регистрация: 12.05.2020
20.02.2026 11:49:34
Цитата
Йцукен написал: А смысл несколько раз подряд обрабатывать, например OnQuote, если каждый раз мы будем обрабатывать одни и те же данные?Или вы предлагаете хранить данные для каждого колбэка?
Если вы не хотите повторно обрабатывать данные, то фильтруйте их. Для фильтрации данных можно создать, для соответствующего вида коллбека, таблицу с фильтруемыми полями, обновляемыми при поступлении новых данных и использовать эту таблицу в начале коллбека с тем. чтобы не обрабатывать ненужные вам повторы.
Пользователь
Сообщений: Регистрация: 02.01.2026
20.02.2026 12:09:03
Цитата
TGB написал: Если вы не хотите повторно обрабатывать данные, то фильтруйте их.
А как вы узнаете, что это повторы, пока не обработаете их?
Цитата
TGB написал: Для фильтрации данных можно создать, для соответствующего вида коллбека, таблицу с фильтруемыми полями, обновляемыми при поступлении новых данных и использовать эту таблицу в начале коллбека с тем. чтобы не обрабатывать ненужные вам повторы.
Вам надо будет сначала, как минимум запросить данные, чтобы сравнить с предыдущими.
Пользователь
Сообщений: Регистрация: 12.05.2020
20.02.2026 12:35:25
Цитата
Йцукен написал: А как вы узнаете, что это повторы, пока не обработаете их?
Вы сначала создаете таблицу фильтрации со значениями полей фильтрации заведомо не совпадающими с ожидаемыми данными.
Пользователь
Сообщений: Регистрация: 30.01.2015
20.02.2026 12:50:07
Цитата
Йцукен написал: колбэки внутри sleep должны вызываться или как?
Sleep останавливает поток main, а функции колбеков вызываются в другом потоке, на который sleep не действует.
Пользователь
Сообщений: Регистрация: 12.05.2020
20.02.2026 13:00:33
Цитата
nikolz написал: Sleep останавливает поток main, а функции колбеков вызываются в другом потоке, на который sleep не действует.
Вы опять только пишите не читая. Мы же с Йцукен обсуждаем не системный Sleep и даже sleep QLua, а предложенный мной запускающий коллбеки. Вам опять надо проложиться между комментариев ?
написал: Sleep останавливает поток main, а функции колбеков вызываются в другом потоке, на который sleep не действует.
Вы опять только пишите не читая. Мы же с Йцукен обсуждаем не системный Sleep и даже sleep QLua, а предложенный мной запускающий коллбеки. Вам опять надо проложиться между комментариев :: ?
Что вы так переживаете? Я написал пояснение о работе sleep в потоках. Так как г-н нефига в этом не понимает, а Вы ему ( я прочитал Ваш ответ)
Да, так называемые коллбеки, должны вызываться внутри sleep (выполняемой в потоке main) с данными из очередей.
Это полная чушь. Ничего внутри sleep не вызывается т к функция sleep выполняется ядром OS. В это время никакой колбек не успеет ничего сделать. -------------------
Пользователь
Сообщений: Регистрация: 30.01.2015
20.02.2026 13:44:29
все что делается внутри sleep - это передается ядру время на которое надо остановить поток. Ядро настраивает таймер на событие -разбудить поток через надцать секунд и передает управление следующему в очереди потоку.
Пользователь
Сообщений: Регистрация: 02.01.2026
20.02.2026 14:18:03
Цитата
В любой теме, где есть обсуждение, Он уже оставил свой след. Не вникая в суть предложения, Он вещает свой «важный» бред.
В любой теме, где есть обсуждение, Он уже оставил свой след. Не вникая в суть предложения, Он вещает свой «важный» бред.
Прекрасно, Наконец-то вы занялись самокритикой. Сами сочинили или опять плагиат?
Пользователь
Сообщений: Регистрация: 12.05.2020
20.02.2026 14:21:42
Цитата
nikolz написал: все что делается внутри sleep - это передается ядру время на которое надо остановить поток.
Вы, как дятел , про свое, не относящееся к обсуждаемому. Вы это читали ?:
Цитата
TGB написал: -- Отличие только в реализации функции sleep. -- При ее вызове с заданным интервалом внутри нее выполняется (код на C++): WaitForSingleObject( , ); // здесь ожидание истечения или выдачи сигнала QUIK (неблокирующей функцией Pulse в служебном потоке) о записи в очереди новых событий. -- Когда sleep "срывается" с , то в ней анализируются очереди (это можно сделать эффективно, используя битовую шкалу непустых очередей скрипта) и выполняются соответствующие с параметрами считанными из очередей. -- Функционально это не отличается от того, что реализовано сейчас, но выполняется в потоке пользователя main.
Пользователь
Сообщений: Регистрация: 30.01.2015
20.02.2026 14:23:41
Цитата
Йцукен написал: , можете написать прсевдокод, как по-вашему, использовать очередь событий?
Вы не читаете форум. Я специально выложил для начинающих писателей не псевдокод, а скрипт на Lua с очередью. Да и в документации на QLua есть еще один пример. -------------------- Ах, ошибся, Вы же не писатель, Вы же ПОЭТ.
Пользователь
Сообщений: Регистрация: 12.05.2020
20.02.2026 14:48:52
Цитата
nikolz написал: Я специально выложил для начинающих писателей не псевдокод, а скрипт на Lua с очередью. Да и в документации на QLua есть еще один пример.
Какой же вы непонятливый. До сих пор не поняли, что обсуждаются не существующие реализации, а вариант изменения этих реализаций. Все таки, похоже, что вы полуинтеллектуальный робот-спамер устаревшей версии, без способности учета контекста обсуждаемой темы при генерации спама.
TGB написал: без способности учета контекста обсуждаемой темы при генерации спама.
У него памяти не хватает, чтобы загрузить весь контекст в память. Вон весь форум загадил кучей новых тем про нехватку памяти.
Пользователь
Сообщений: Регистрация: 02.01.2026
20.02.2026 15:16:51
Цитата
TGB написал: Вы сначала создаете таблицу фильтрации со значениями полей фильтрации заведомо не совпадающими с ожидаемыми данными.
Ну т.е., фактически запросить данные, обработать их (как минимум сравнить с предыдущими). Логичней было бы, чтобы терминал не дублировал пропущенные колбэки, по которым скрипт не получит новых данных. Хотя, кому-то наоборот нужна вся история изменений (для индикатора какого-нибудь). Не зря же есть CreateDataSource для параметров инструментов. Но тогда QUIK должен хранить всю историю изменений. В общем, этот момент вам надо продумать.
Пользователь
Сообщений: Регистрация: 12.05.2020
20.02.2026 17:57:57
Цитата
Йцукен написал: Логичней было бы, чтобы терминал не дублировал пропущенные колбэки, по которым скрипт не получит новых данных.
Это хорошее ваше предложение можно сформулировать следующим образом: функциональность обработки событий QUIK расширить, добавив в API пользователя функцию задания свойств служебных очередей событий: 1) длин очередей; 2) функций фильтрации событий перед их записью в соответствующие очереди; 3) приоритетов обработки очередей; 4) может быть что то еще.. Все свойства имеют значение по умолчанию.