TGB (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 12 13 След.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
 
Цитата
Владимир написал:
вся задача организации торговли прикладная с головы до пят, и любые попытки привнести сюда системные штучки-дрючки - тем более, глубоко системные, как в данном случае, ни к чему хорошему не приведут.
Очень филосовское замечание :smile:
Где вы видите системные штучки? Код написан на чистом Lua (даже циклов нет :smile:).
---
 Я не понял ваших замечаний. Что в коде не так?
 Здесь выложен конкретный код, который, возможно, пригодится для устранения ситуации,  описанной в комментарии: https://forum.quik.ru/messages/forum10/message54811/topic5823/#message54811
или для варианта модификации QLua, описанного в п.2 комментария: https://forum.quik.ru/messages/forum10/message57220/topic5823/#message57220
и освобождающего скриптера от проблем параллелизма в QLua, Этот код может оказаться интересным и еще кому-нибудь.
  При описании кода я коротко отметил его существенную особенность, Для кого-то из читателей будет понятно, почему это сделано так.  Что в этом плохого?
  Вы же можете пользоваться своими "безразмерными" прикладными очередями или, например, использовать безразмерную (очень простую) очередь, код которой приведен в описании упомянутой мною ситуации. Но скорее всего, вам не нужны никакие очереди. Ну и замечательно.
Кривые шибки в QLua
 
Цитата
Старатель написал:
это уже вне зоны ответственности скриптера, а ошибка в реализации многопоточной модели QLUA.
1. Для устранения вашей конкретной ситуации, возможно, подойдет вариант реализации очередей, приведенный в моем комментарии https://forum.quik.ru/messages/forum10/message57219/topic6198/#message57219
2. Вообще, существует сравнительно несложный вариант заметно улучшить QLua (сделав его однопоточным для скриптера) без изменения его внутренней архитектуры:
1) добавить в API QLua функцию <задание схемы обработки колбеков>, которую скриптер может (но не обязательно) вызвать в начале своего скрипта с параметром задания схемы;  если эта функция не вызвана, то колбеки обрабатывыются так, как это делается сейчас по старой схеме;  дополнительно, в этой функции можно бы задавать версию Lua, а возможно и еще что-нибудь;  при задании новой схемы, внутри QLua автоматически реализуется схема взаимодействия main с колбеками через две потокобезопасные эффективные очереди (как обеспечить их эффективность, наверное, понятно), одна из которых обслуживает колбеки фондового рынка, а вторая, колбеки событий таблиц QUIK, созданных скриптером;
2) при работе по новой схеме обработки колбеков, в API QLua добавить еще две функции: <функция подписки на события фондового рынка> и <функция подписки на события пользовательских таблиц >; в этих функциях скриптер может, в виде списка (в таблице) подписаться на события в соответствии с существующими именами колбеков;  реализация подписки разработчиком QUIK может быть сведена к автоматическому созданию (скрытых) от пользователя функций колбеков, вызываемых, как это делается сейчас, и записывающих свои параметры с добавлением «от кого параметры» в соответствующие очереди;
3) для работы с очередями по новой схеме в API QLua добавить две функции чтения (?возможно также и выполнения некоторых дополнительных функций), соответственно очередям;  при чтении очередей в считываемой таблице передаются: <имя события>, <время записи в очередь>, <параметры в том виде, как они описаны, в существующих колбеках>.
   При работе по второй схеме, QLua для скриптера становится однопоточным и снимаются многие сложные проблемы. Причем, остается возможность не затрагивать и тех скриптеров, которые по тем или иным причинам не станут уходить от старой схемы.
----
 Общая схема работы скриптера в новой схеме обработки событий QUIK.
<Заказывается новая схема обработки событий >
<Выполняется подписка (вместо написания функций колбеков) на обрабатываемые события QUIK>
<В функции main, в цикле  читаются две очереди и обрабатываются считанные параметры событий>
-------
 Мною была описан некий, как мне представляется, не сильно сложный вариант реализации избавления QLua от проблем параллелизма, связанных с его существующей реализацией.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
 
Реализация очередей в OS_Quesha.
1. Кроме ранее описанного контроля, в системе выполняется периодический контроль текущих размеров всех ее очередей.  При создании каждой очереди задается ее предельно-допустимый размер. Если текущий размер, какой то очереди превышает 75% предельно-допустимого, в системе начинает выдаваться об этом сообщение.
2. Существенная особенность построения очередей в OS_Quesha состоит в том, что они строятся на таблицах, в которых после их создания, нет вставок или удалений их полей (записей). В процессе работы с очередями изменяются только значения существующих полей, обеспечивающих запись/чтения этих очередей. Структура таблиц очередей «заморожена». Это обеспечивает в многопоточном режиме возможность эффективной синхронизации работы с очередями на уровне их полей, а не на глобальном уровне самих очередей.
  Далее выложен работающий код реализации очередей с учетом выше написанного для частного случая, когда один поток в нее пишет, а другой читает  (!не допустимы чтения или записи в нескольких потоках):
Код
---- Реализация циклических потокобезопасных очередей без синхронизации для случая, когда один поток в нее пишет, а другой читает  (!не допустимы чтения или записи в нескольких потоках)------
local Queue_safe = {
  ---  size_Queue - размер очереди  ----
  new = function (self, size_Queue)
    local  Queue = {}
    local  cycl = {}      -- таблица-массив хранения элементов очереди
    for i =1, size_Queue do 
        cycl[i] = 0 
   end
   Queue.cycl = cycl
    Queue.QueueLength = size_Queue  --- размер очереди    ---
    Queue.RecordPointer = 1   ---  указатель записи  (изменяется только "писателем")     ---
    Queue.ReadingPointer = 1 ---  указатель чтения  (изменяется только "читателем")     ---
   Queue.written_down = 0   --- количество записанных элементов ---
   Queue.read = 0  --- количество считанных элементов ---
    return setmetatable(Queue, {__index = self})     --- для переключения на Queue_safe при обращение в созданной таблице к push, pop, size  ----
  end,
  
  --- Записываемое в очередь значение не может быть nil  --
  --  Результат: 0 - запись выполнена;  1 -  запись не выполнена (нет места) 
  push = function (self, v)  
        if v == nil then  error(' !!! В очередь нельзя записывать  nil ')  end
      if  self.written_down - self.read >= self.QueueLength then      ----- некуда писать  ----
              return (1)   
        end
        local  cycl = self.cycl
        local pwt=  self.RecordPointer
      cycl [pwt] = v
      local pwf =  pwt +1
        if  pwf  > self.QueueLength then
             pwf=1
        end
        self.RecordPointer = pwf  --- следующая позиция для записи (возможно занятая) --   
      self.written_down = self.written_down + 1
        return (0)
  end,
 
  ---  Два результата: 1) элемент или nil;     2) признак: 0 - очередь после чтения пуста;  > 0 - количество непрочитанных элементов;   -1 - очередь пуста в момент чтения;
  pop = function (self)
      local n = self.written_down - self.read 
      if  n == 0 then
           return nil, -1  --- нет данных
      end
     local  cycl = self.cycl 
     local prt=  self.ReadingPointer
     local v = cycl [prt]
     cycl [prt] = 0      ---  чтобы не было "висячих" ссылок на ссылочные объекты  ----
      prt =  prt +1
      if  prt  > self.QueueLength then
            prt = 1
      end
     self.ReadingPointer = prt
     self.read = self.read + 1
     return  v,  n - 1 
  end,

  size = function (self)
    return self.written_down - self.read
  end
}
----------------------------------------------------------------------
                                                                                            ------  Тесты  -----
local T 
local v
--[[
 --  1.  Этот фрагмент (использование потокобезопасных функций QLua)   (100 000 записей и чтений)  выполняется за ~3560 милисекунд ---
T = {}
for j = 1, 100  do 
  for i = 1, 1000 do  --- запись в очередь
     table.sinsert (T, 'sd')   
  end

  for i = 1, 1000 do  --- чтение из очереди
     v = T[1]
    table.sremove (T, 1)
  end
end
do return end      ------
 -----------------------------------------------------------------
--]]

 --  2. Этот фрагмент (использование Queue_safe)   (100 000 записей и чтений)  выполняется за ~55 милисекунд ---
T = Queue_safe:new(1200) 
  
 for j = 1, 100  do 
  for i = 1, 1000 do  --- запись в очередь
     T: push('sd')
  end

  for i = 1, 1000 do  --- чтение из очереди
     v = T: pop()
  end
end
--------------------------------------------------------------

  Относительно выложенного кода можно отметить следующее.
1. Это сильно упрощенный, работающий вариант реализации очередей, которые используются в OS_Quesha.
2. Особенностью этих очередей, при их создании, является необходимость задания их предельного размера. При записи в очередь, выдается признак успешности этой записи, либо отсутствия места в очереди.
3. Работа с создаваемыми очередями потокобезопасна без синхронизации при их использовании в QLua между колбеками и main.
4. Скорость выполнения операций запись/чтение не зависит от текущей длины очередей (в отличие от очередей, реализуемых с помощью table.sinsert и table.sremove, в которых скорость операций с увеличением текущей длины очереди, резко падает).
Кривые шибки в QLua
 
Цитата
Старатель написал:
Абсолютно беспочвенное утверждение, говорящее об отсутствии понимания работы обсуждаемого кода.
 Вы имеете ввиду, что для записи и чтения в очередь используются свои указатели и, я бы с вами согласился, если бы не существовал общий объект, в котором это происходит (таблица хранения очереди в которую вставляются и из которой вычеркиваются элементы очереди). Вы уверены, что работа с таблицей при изменении ее структуры в Lua реализована потокобезопасно? Где это написано?
Кривые шибки в QLua
 
Цитата
Старатель написал:
В качестве разминки сделайте перезаказ обезличенных сделок (или переключитесь на другой сервер) ближе к концу торговой сессии и посмотрите, с какой задержкой будет обрабатываться ваша очередь и расход памяти скриптом.
  Очередь не моя, а разработчика QUIK.
  Мне не известно как вы обрабатываете обезличенные сделки (сколько это может занимать ресурсов ПК), поэтому я запустил тест для проверки времени выполнения потокобезопасных функций реализации только очереди:
Код
----  Скрипт -тест  ----
 --  Этот фрагмент выполняется  ~500 милисекунд ---
local T = {}
local v
for j = 1, 10  do 
  for i = 1, 1000 do  --- запись в очередь
     table.sinsert  (T, {'sdfdfmffmf', 57})
--     v = T[1]
--    table.sremove(T, 1)
  end

  for i = 1, 1000 do  --- чтение из очереди
 --    table.sinsert  (T, {'sdfdfmffmf', 57})
     v = T[1]
    table.sremove(T, 1)
  end
end


  10000 обращений (запись, чтение, удаление) за 500 миллисекунд.
Понятно, что тест искуственный (без взаимодействия с колбеками), но какое то представление о скорости работы очереди и допустимой ее длине он дает.
Заметного роста памяти QLua я не заметил.

Цитата
Старатель написал:
Цитата TGB  написал: В вашем коде, по вашей ссылке, используется в двух потоках потоконебезопасная очередь OnAllTrades.
И?
Это значит, что при работе с такой очередью могут возникать ошибки синхронизации, которые могут порождать наблюдаемые вами последствия.

==========================
Цитата
_sk_ написал:
Очередь, реализованная Старателем, в этом случае корректно работает и без блокировок.
  А что же ситуации время от времени возникают?
Кривые шибки в QLua
 
Цитата
Старатель написал:
Старатель  написал:
local hour = 0+os.date('%H')
выскочила такая ошибка: attempt to perform arithmetic on a nil value
 Меня заинтриговала ошибка, которую вы обнаружили, в таком коротком коде.
Напишите, пожалуйста:
  Как часто выполняется в скрипте приведенный вами фрагмент?
  Где это выполняется: в main или колбеках?
-----------------------
Цитата
Старатель написал:
Также  ошибка attempt to call a nil value (method 'pop') в 9.1 никуда не пропала. Откуда здесь nil?
В вашем коде, по вашей ссылке, используется в двух потоках потоконебезопасная очередь OnAllTrades.
В API QLua есть функции реализации потокобезопасной очереди, созданные разработчиком QUIK:  table.sinsert, table.sremove.
Пример использования потокобезопасной очереди: https://forum.quik.ru/messages/forum10/message56397/topic6356/#message56397
Работа функций OnStop() и SetCell(), Подвисает скрипт
 
Цитата
Roman Azarov написал:
Просьба уточнить, о каких конкретно функциях, вызываемых из OnStop(), идет речь?
  Цитата (не точная) из известной юморески: "Принесите справки от всех женщин, что вы на них не женаты."  :smile:
Отладка QUIK 8.13
 
Об атомарности операций.
 Рассуждения об атомарности операции без определения ее области реализации это рассуждение о погоде без определения, к чему это относится (к Арктике или Антарктиде).
 Все операции скрипта, по отдельности, команды байт-кода или вызов C-функций являются атомарными, но в тоже время, выполнение скрипта, в целом, может быть и не атомарным (потоконебезопасным). Это связано с тем, что между упомянутыми операциями могут возникнуть переключение потоков, изменяющее контекст выполнение локально-атомарных операций. На самом деле, для выяснения потокобезопасности (атомарности выполнения скрипта в целом) достаточно выявить общие данные, модифицируемые в main и в основном служебном потоке QUIK, генерирующем вызовы колбеков скрипта. Если таких данных нет (а это часто можно обеспечить), то бессмысленно гадать об атомарности отдельных операций скрипта (скрипт выполняется атомарно, то есть, потокобезопасно, если нет таких данных).
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
 
Дополнительно к тому, что было написано в моих предыдущих комментариях относительно OS_Quesha.
1. То, что написано в них, не относится к начальному «освоению» QLua. Это может оказаться интересным, наверное, тем, кто в этом «поварится» некоторое время, после которого проявятся те проблемы, о которых я пишу.
2. Моя позиция относительно любых средств разработки программ: они должны облегчать жизнь пользователя таких средств. Если есть возможность обеспечить такое, то пользователя надо, освобождать от сложных проблем параллельного программирования или обеспечения надежности разрабатываемых программ.
3. OS_Quesha, обеспечивая многопоточность скрипта, написанного на QLua, полностью (если не используются общие модифицируемые в нескольких потоках данные, для работы с которыми есть средства для «продвинутых» разработчиков) освобождают разработчика таких скриптов от проблем параллельного программирования и обеспечивает их надежность.
4. В продолжение моего комментария, в котором описаны средства обеспечения надежности скриптов QLua с использованием контрольных точек.
  Известными проблемами любых программ являются:
1) их возможные блокировки при обращении к разделяемым ресурсам (с синхронизацией доступа к ним);
2) их возможные зацикливания (из-за ошибок в них);
3) «утечка» памяти  (из-за ошибок в них).
 Не существует универсальных, автоматических решений этих проблем. Уже хорошим решением может быть: ранняя диагностика таких проблем и это обеспечивается в OS_Quesha.
 В OS_Quesha выполняется контроль:
1) блокировок ее потоков;
2) зацикливания ее потоков;
3) утечки памяти QLua;
4) утечки памяти самого QUIK.
 Так как нормальные автоматические обработки описанных выше ситуаций мне не известны (они, как правило, связаны с существенными ошибками в скрипте, или QUIK), то по ним выдается четкая диагностика, а далее есть два варианта: продолжение работы скрипта (с продолжением выдачи упомянутой диагностики) или его перезапуск (возможно с перезапуском QUIK).
   В обобщенной классификации, OS_Quesha является «форком QLua», и в нем нет тех проблем, которые описаны в моем комментарии, относительно QLua, в соседней ветке «Отладка QUIK 8.13»; https://forum.quik.ru/messages/forum10/message57036/topic6356/#message57036
Отладка QUIK 8.13
 
В предыдущих комментариях, при обсуждении конкретного, протестированого  в непрерывном недельном прогоне, решения (в виде мизерной правки в 4-х местах исходников QLua), исправляющего, по моему мнению, существующую в QLua ошибку, было написано много текста, в котором можно «сломать голову».

  На самом деле все достаточно просто.
    В QUIK запускается единственный служебный «основной» поток, который об-служивает колбеки всех запущенных скриптов пользователя и его созданных таблиц QUIK.
    В текущий момент существует, по крайней мере, два варианта, когда скриптер может, «случайно», выполнением кода своего скрипта, заблокировать «основной» поток (при этом перестают запускаться колбеки всех запущенных в QUIK пользователем скриптов и все скрипты «слепнут»:
1) скриптер написал непосредственно в запуске какого-то своего колбека длительно выполняющуюся функцию (почему бы нет?);
2) скриптер сумел написать в main длительно выполняющийся фрагмент байт-кода, в котором нет вызовов C-функций (почему бы нет?).
  Первый вариант лечится, если следовать рекомендациям разработчика QUIK по обработке колбеков.  При этом, все что делается в main пользователя, становится однопоточным (относительно «основного» потока). «Основной» поток, при обработке колбеков, выполняет только короткие записи параметров колбекков в очереди. Причем, в этом случае, при написании и редактировании скрипта, заниматься синхронизацией с «основным» потоком не надо вообще.
  Второй вариант скриптер сейчас может лечить каждый раз, при редактировании скрипта, анализируя  его текст на наличие фрагментов «длинных» байт-кодов и вставляя в них, в «?? нужных» местах какую-нибудь, функционально  пустую C-функцию.  Нужно ли это скриптеру, если это можно вылечить, внеся, предложенные мною, исправления в QLua?
  Могу ли быть ошибки, в предложенном мною? В любом коде ошибки могут быть, но это уже как-то протестировано (непрерывно в течении недель) да и разработчик QUIK может это потестировать.
Отладка QUIK 8.13
 
Цитата
Anton написал:
Потому что арка не знает, как устроен луа.
 Могут узнать, так как есть исходники Lua и это полное описание Lua (вы, что это не понимаете?).

Цитата
Anton написал:
И вы не знаете.
 Знаю. Так как есть исходники Lua. И вы можете узнать, никто не запрещает.

Цитата
Anton написал:
Если бы вы это предложение выкатили команде луа, еще куда б ни шло, там хоть последствия понимают.
 Команде Lua это не нужно. Как только вы встраиваете Lua в свою систему, за последствия отвечаете вы (почитайте в тексте исходников Lua комментарии; они же в свободном доступе).

Цитата
Anton написал:
Еще раз, в текущем луа есть удобная особенность атомарности исполнения байткода. Вы это хотите сломать. Я против самой идеи это ломать.
 Конечно, при этом исчезает интересная возможность многочасового гадания в коде скрипта на атомарность/неатомарность  :smile:, если не следовать рекомендациям разработчика QUIK по взаимодействию с колбеками. Но самое интересное, даже, если вы убежденный противник рекомендаций разработчика Quik и не используете потокобезопасную очередь между вызовом колбеков и main, то, если нет общих данных, модифицируемых в вызовах колбеков и в функциях вызываемых в main, то гаданием атомарность/неатомарность можно, вообще, не заниматься.
Цитата
Anton написал:
Как ее решить без ковыряния в кишках луа, я предложил.
Где ваш протестированный вами код?
Отладка QUIK 8.13
 
Цитата
Владимир написал:
TGB , Дык я же давал чуть не десяток предложений в одном флаконе, и чуть ли не все они были зарегистрированы.
  Вы за то, чтобы поток генерации колбеков блокировался фрагментами байт-кода?
  У вас есть конкретные замечания и возражения против моего конкретного протестированного предложения по устранению этих блокировок?
  Вы за то. чтобы был реализовано гипотетическое, "лабударно-завиральное", никак не проверенное предложение Anton, выдвинутое, как мне, но возможно ошибочно, кажется только для дискредитации того, что уже протестировано?
Отладка QUIK 8.13
 
Опять цитата не моя, а Владимира, Извиняюсь перед собой :smile:
Отладка QUIK 8.13
 
Цитата
TGB написал:
Скрипт свой я уже и не помню
 Я тоже свою систему почти не помню.
  Но вы же? в свое время? "нахлебались", по "полной", на таблицах QUIK (или нет). Вы что, хотите, чтобы и остальные пользователи получили "свое"?
  То, что вы просите, можно сделать самому. Вы, ведь, системный программист?
Мне, просто бывает интересно (когда есть время), как "кипит" "социальный бульон" в текущее время.
Отладка QUIK 8.13
 
swerg, извиняюсь.  В моем предыдущем комментарии все цитата от Anton.
Отладка QUIK 8.13
 
Anton , зачем вы все время требуете продолжение «марлезонского балета»?
Ну хорошо, продолжим.

Цитата
Anton написал:
Я писал сначала, что не надо луа патчить для решения вашей проблемы?
  На самом деле это проблема не моя. Для себя эту проблему я решил достаточно давно (аж в 2019г.,  когда разработал свою систему создания торговых роботов в QUIK). Утомлять вас здесь тем, как это у меня решено, я не буду.

Цитата
swerg написал:
Я написал, как решить ее без патча луа? Написал. Еще что-нибудь?
    Ну, наверное, вам бы стоило протестировать (на интервале, хотя бы, трех суток) предложенное вами решение у себя. И изложить его здесь с той же детальностью, как это сделал я.
 Наверное, из двух работающих решений можно бы выбрать то, которое лучше.
    Возможно, я бы и сам отказался от своего предложения. Я же не «упертый» и с дельными замечаниями, сделанными мне, легко соглашаюсь (можете посмотреть некоторые мои комментарии). А, кстати, почему вы так упорно боретесь против «форка lua»? Как то это сильно смахивает на борьбу за невинность девушки, которая уже больше года замужем.

Цитата
Anton написал:
Нагуглить для вас критическую секцию с таймаутом или сами сумеете?
Этого делать не надо, а лучше поищите закладки в моем коде  :smile: .
Отладка QUIK 8.13
 
Цитата
swerg написал:
Вообще ни о чем не говорит.
Я в начале 2021г. как-то сравнивал количество внешних функций Qlua и Lua. В Qlua их почти на сотню больше.
Каталог luac-скрипта, выполняемого через dofile
 
В Lua 5.4 у меня работает это.
Внутри откомпилированного скрипта, в начале:
<code>
-- Функция  ---
local function dofile_exe_path()
  local str
  for i = 2, 4 do --- поиск корневой функции, вызывающей script_path, начиная с функции в которой вызвана script_path
--     message (tostring(  debug.getinfo(i) ))
     if  debug.getinfo(i)  then   ----
    str = debug.getinfo(i, 'S').source
 else
    break
 end
  end
  return  str
end

local path_script
path_script = dofile_exe_path ()
message( path_script  )  
-- Результат message строка вида :   dofile('<Путь к оттранслированному скрипту>')

<code>
Далее, наверное, разберетесь сами.
Отладка QUIK 8.13
 
Я уже думал, что наш диалог завершен, но вы пишите такие фантазийные, детективные тексты, что мне стало интересно.
Цитата
Anton написал:
но тем, кто будет писать не как я, подложу-ка я закладочку и выкручивайтесь как выйдет". Вот так вот получается.
 Где я такое написал?
Если вам кажется, что это находится в опубликованном мною коде, то укажите, где вы нашли такую закладку?

Цитата
Anton написал:
Я хорошо понимаю, чего вы добиться хотите
 Вы что, экстрасенс  :smile: ?
Я же просто представил протестированный на своем стенде (на котором в сое время тестировал исправление ошибки синхронизации QLua) код исправления блокировок потоков длинными участками байт-кода. Это короткие правки в 4-х местах кода QLua. Их можно изучать визуально, проверять экспериментально, искать в них "до посинения" закладки.

Цитата
Anton написал:
Это невозможно в принципе
 Вот и замечательно! Хорошо построенная программная система должна быть защищенной.

Цитата
Anton написал:
В то же время у нас есть виртуальная машина, поэтому арка может добавить отслеживание зависших скриптов, если вместо кондовой CRITICAL_SECTION в качестве лока будет использовать нечто иное с возможностью таймаута на вход. Если таймаут истек и секция не захвачена, весь скрипт убивается как в случае ошибки, все дела. В идеале сначала дергается некий юзерский колбек с вопросом "тебя прибить или сам отвиснешь", если ответил отвисну и не отвис, в морг. Вот что вам стоило бы попросить у арки, а не луа ломать.
 И это предлагается вместо "прозрачных" правок в 4-х места кода, вносимых туда в течении пяти минут? Как-то очень сложно (я бы до такого не додумался  :smile: ) и вот уж куда удобнее вставлять закладки.
Отладка QUIK 8.13
 
Цитата
Anton написал:
теперь оказывается надо писать только так и никак иначе
Если вы это так поняли, то, придется, все-таки стоит пояснить.
  Конечно же, каждый разработчик может писать скрипты как хочет:
1) постоянно, после очередной редакции скрипта, анализируя код на его атомарность/неатомарность (марлезонский балет);
2) не заморачиваясь проблемама синхронизации с колбеками (вообще не зная что такое атомарность)
И это никак не связано с тем, останется ли блокировка потоков участками байт-кода (как это про-исходит сейчас) или это будет устранено.

Цитата
Anton написал:
этот марлезонский балет достал уже
Согласен.
Отладка QUIK 8.13
 
Цитата
Anton написал:
А на других примерах - произойдет. Это типичнейший паттерн вообще-то, как тут можно НЕ увидеть проблем...
 Похоже, примеры с вами можно бы было обсуждать бесконечно  :smile:
----
Цитата
Anton написал:
Об чем и речь, весь код У ВСЕХ будет в этих костылях просто потому, что вам кровь из носу хотелось чонить в квике починить, пусть даже и не сломанное.
 Опять декларации и страшилки. Но это же можно бы было сформулировать короче: «Не тронь!» :smile:
Вы что, это не читали?:
Цитата
TGB написал:
дело обстоит еще проще. Если вы знакомы с документом разработчика QUIK «Использование Lua в Рабочем месте QUIK.pdf», то его в разделе «2. Взаимодействие потоков Lua скрипта» описана рекомендуемая схема обработки колбеков фондового рынка, которую можно распространить и на обработку колбеков событий таблиц QUIK. Если придерживаться этой схемы, то проблем многопоточности (! из-за основного потока обработки колбеков) в скрипте пользователя не будет вообще: ни в «чистом» Lua-коде ни в смешанном. И не надо ни чем извращаться ни в одной строчке скрипта так как при этом он становится однопоточным (относительно основного потока обработки колбеков). Вы можете почитать комментарии, начиная с  https://forum.quik.ru/messages/forum10/message56387/topic6356/#message56387  , в которых это обсуждается с демонстрацией кодов, рекомендуемых разработчикам QUIK.   Если же в скрипте не используется схема обработки колбеков, рекомендованная разработчиком QUIK, то преобразование любого такого скрипта в функционально эквивалентный, но с рекомендованной схемой, элементарное.
  или вы убежденный противник решения разработчика QUIK, приведенного в указанном фрагменте текста?
  Попытаюсь сформулировать, то, что написано там более понятно и короче.
  Если использовать то, что написано в этом фрагменте, то никакой синхронизации с потоком, обрабатывающем колбеки  не требуется. Ни нужны никакие костыли. Не требуется многочасовой анализ кода скрипта на атомарность/неатомарность, (ворк/неворк  :smile: ). Причем, это справедливо как для существующих версий QLua, так и в случае реализации предлагаемого мною решения, устраняющего ошибку блокировки потоков длинными участками байт-кода.
 Сформулировать это еще короче я уже, наверное, не смогу  :smile:
Отладка QUIK 8.13
 
Цитата
Anton написал:
Модельку такую можно сделать, а как в реальной жизни к такому коду можно прийти, я прошу продемонстрировать.
  Пусть это и демонстрирует реальная жизнь :smile:

Цитата
Anton написал:
Видите? Я табличку атомарно спрятал в локальную переменную и спокойно удалил. Когда DestroyTable снимает лок, мейн видит вместо таблички нил и все правильно понимает.
Точно также, если переключение (! оно не может возникать внутри команд Lua-машины, а только между ними) в байт-коде вдруг возникнет после tid = nil, но до DestroyTable, то оно снимает лок, мейн видит вместо таблички нил и все правильно понимает. При этом исполнение кода в мейн не сможет блокировать поток обработки колбеков и DestroyTable тоже успешно выполнится. В чем вы видите проблемы?

Цитата
Anton написал:
После вашего улучшения такое без критической секции не сделаешь, а их в луа нет, если помните. Придется ради вот этой фигни извращаться. И так на каждой строчке.
 Я помню, что в Qlua есть потокобезопасные функции, обеспечивающие функциональность критической секции и нет проблем использовать их в представленном вами примере (вы с этим сами можете разобраться и я не буду тратить время на то, как это можно сделать), Я только не очень понимаю зачем это может потребоваться в приведенном вами примере?
 Но дело обстоит еще проще. Если вы знакомы с документом разработчика QUIK «Использование Lua в Рабочем месте QUIK.pdf», то его в разделе «2. Взаимодействие потоков Lua скрипта» описана рекомендуемая схема обработки колбеков фондового рынка, которую можно распространить и на обработку колбеков событий таблиц QUIK. Если придерживаться этой схемы, то проблем многопоточности (! из-за основного потока обработки колбеков) в скрипте пользователя не будет вообще: ни в «чистом» Lua-коде ни в смешанном. И не надо ни чем извращаться ни в одной строчке скрипта так как при этом он становится однопоточным (относительно основного потока обработки колбеков). Вы можете почитать комментарии, начиная с https://forum.quik.ru/messages/forum10/message56387/topic6356/#message56387 , в которых это обсуждается с демонстрацией кодов, рекомендуемых разработчикам QUIK.
  Если же в скрипте не используется схема обработки колбеков, рекомендованная разработчиком QUIK, то преобразование любого такого скрипта в функционально эквивалентный, но с рекомендованной схемой, элементарное.
Отладка QUIK 8.13
 
Цитата
Anton написал:
Было уже написано  в этой самой теме не мной. И другие подобные сценарии. Многие вещи, которые в 5.1 требовали длл и никак иначе, теперь можно сделать в скрипте. Вы это хотите сломать. Это уже достаточный аргумент, чтобы не поддержать идею. Можно и в обратную сторону спросить - а что это всем даст? Как скриптер от этого выиграет? Или хотя бы пример делающего что-то полезное кода без сишных вызовов, который иначе ну никак нельзя написать.
  Все, что вы написали (включая ссылку) как-то декларативно и нет конкретики. Типа, это не надо делать, потому что не надо.
 Но в вашем комментарии есть фразы, на которые я попытаюсь ответить или задать вопросы.
1.  Каким образом что-то будет ломаться, если будут переключение потоков внутри «чистого» кода Lua (байт-кода)?
---
 Сейчас переключение потоков в QLua возможно, и выполняется при вызове в скрипте C-функций, которых в рабочем скрипте обычно достаточно много (начиная со sleep). И при этом ничего не ломается.
  Что изменится в описанном выше качественно, если будут переключения на участках байт-кода? Ничего!  Вы же можете, без проблем, в существующий скрипт добавить, для своих целей, новые вызовы C-функций внутрь существующего байт-кода и это нормально.
 Предлагаемый мною вариант переключения внутри байт-кода это, по сути, добавление очень эффективного вызова «пустой», ничего не делающей C-функции через определенный интервал выполнения команд байт-кода. Это обеспечивает возможность переключения потоков внутри байт-кода и устранение блокировки потоков длительными фрагментами байт-кода.
  Интервал вызова «пустой» C-функции может быть таким (например, 1000), что дополнительные «окна» переключения потоков  практически никак не влияют на скорость выполнения скрипта (это проверено мною экспериментально). При этом разработчику скрипта. дополнительно к тому, чем занимается его скрипт, ничего делать не надо.

2.  Что это даст всем (скриптерам)?
 Сейчас, если в скрипте выполняется  длительный участок байт-кода main,  то на время его выполнения, блокируется выполнение основного потока, обрабатывающего колбеки всех запущенных скриптов пользователя и обслуживающего события таблиц QUIK. Все аналогично, если описанное выше, происходит в функции, вызванной в колбеке.
 -----
Для демонстрации выигрыша скриптера от реализации обсуждаемого предложения рассмотрим, например, следующую ситуацию.
У пользователя запущено два скрипта (почему бы нет, они будут выполняться в разных потоках):
первый скрипт продуктив, который реально торгует на рынке (обрабатывает колбеки);
второй скрипт продуктив, который тоже реально торгует на рынке (обрабатывает колбеки).
  Если во втором/первом скрипте в какой-то момент времени  будет обрабатываться длинный байт-код в main и при этом в нем вызовется колбек, то поток обработки колбеков всех скриптов будет заблокирован. При этом перестанут обслуживаться и колбеки первого/второго скрипта. Это может произойти неожиданно и в самом неподходящем месте и породить неприятные последствия для торгующего. Этого ожидает пользователь? Надо ли скриптеру, при каждой редакции своих скриптов анализировать свой код на возможность возникновения описанной ситуации или других похожих?
----
 Если бы было реализовано то, что я предлагаю, то описанных выше блокировок не было бы.
 Кто-то скажет, что описанный выше пример надуманный, редкий и так далее. Но, те, кто разрабатывал более-менее серьезные программы, наверное, понимают, что если есть баг в программе, то рано или поздно он может проявиться.
3. И вопрос Антону: все-таки, интересно, какую конкретную функциональность в своих разработках вы реализуете, использую блокировку потоков выполнением длинных участков байт-кода?
Отладка QUIK 8.13
 
Цитата
Anton написал:
А форк или не форк мне не интересно.
 Ну, не я же начал про  форки.  А ответил потому, что подумал, что, вдруг, узнаю что-то новое.

Цитата
Anton написал:
Вам стало скучно, вы придумали какую-то околесицу и пытаетесь ее всем навязать.
Насчет околесицы не согласен, почитайте наше с вами общение, начиная с комментария: https://forum.quik.ru/messages/forum10/message54757/topic6356/#message54757

Цитата
Anton написал:
Мне не нужны случайные переключения контекста посреди байткода. Мне они помешают.
  Это уже интересно.
Опишите как такие переключения вам мешают. Мне они никак не мешаю.
Отладка QUIK 8.13
 
Цитата
Anton написал:
Того же самого я не хочу достигать, бо не вижу проблемы в существующем поведении и, более того, считаю такое поведение весьма удачным, случайно оно возникло или намеренно.
То есть, вы вполне удовлетворены тем, что QLua является «форком луа» (если вы отвергаете все остальное, приведенное мною в обоснование того, что QLua, похоже, форк ) хотя бы по причине:
Цитата
TGB написал:
1) исходники Lua были изменены для обеспечения многопотоковости QLua (смотрите мой комментарий  https://forum.quik.ru/messages/forum10/message54696/topic6356/#message54696) ;
И тогда что это:
Цитата
Anton написал:
вы предлагаете создать форк луа и встроить в квик именно форк. Это дорога в ад. Надеюсь, в арке это понимают.
Отладка QUIK 8.13
 
1.
Цитата
Anton написал:
Там вы как раз неправильно делаете правильные вещи ) То же самое достигается без изменения кода луа.
  То, что я предложил очень конкретно, работает (прочитайте эту ветку сначала).
Где ваше предложение достичь того же самого без изменения кода Lua?

2. Здесь, как я понимаю, мы с вами обсуждаем конкретное предложение, протестированное  на моем стенде:
Цитата
TGB написал:
Прошло два месяца. Просьба к поддержки: сообщить результаты рассмотрения пожеланий.
 ----  
  Второе пожелание факультатив и, наверное, его стоит рассматривать после устранения критических ошибок, но первое пожелание (было отмечено сразу при описании пожеланий) это устранение ошибки.   Напоминаю:   Бывают ситуации зависания в QLua, когда основной поток обслуживания колбеков всех скриптов пользователя, а также таблиц QUIK (это не таблицы Lua), блокируется выполнением  длинного цикла пользовательской программы на «чистом» Lua, в котором нет ни вызова seep ни вызова других C-функций.  Это может порождать ошибки, которые для многих пользователей QLua (использующих несколько запускаемых скриптов)  являются неожиданными и труднообъяснимыми. Блокируются выполнения колбеков всех скриптов из-за выполнения длинного цикла пользовательской программы на «чистом» Lua в каком-то из запущенных пользователем скриптов.
-----
   Есть простой вариант реализации первого пожелания, кстати, совместимого со вторым  (далее список изменений реализующих этот вариант в в тексте исходни-ков Lua ):
1. В файле   lstate.h  после строки:  lu_byte allowhook;добавить: int Счетчик_для_переключения_State;
2. В файле   lstate.с  после строки:  L->errfunc = 0;добавить:  L->Счетчик_для_переключения_State = 0;
3. В файле   lstate.с  после строки:  L1->stacksize = BASIC_STACK_SIZE;добавить:  L1->Счетчик_для_переключения_State = 0;
4. В файле   lvm.с  после строки:  StkId ra;добавить:  
  if (++L->Счетчик_для_переключения_State > 1000) {   //  1000  надо задать кон-стантой  
     L->Счетчик_для_переключения_State = 0; lua_unlock(L); lua_lock(L);
  }
------------------------------------  
В чем проблема реализации первого пожелания?
  Вместо того, чтобы сделать конкретные замечания по выше предложенному, вы пускаетесь в филосовские рассуждения о том, после какой, внесенной в исходники Lua запятой, считать его «форк луа».  
   Причем, напомню вам, что по вашему же предложению (кстати, поддержанного в комментариях мною) были внесены разработчиком QUIK заметные изменения в обработку исключительных ситуаций Lua.  Наверное, вы ответите, что изменения в обработку исключений не делают Lua «форком луа» :smile: .
Отладка QUIK 8.13
 
Цитата
Anton написал:
TGB ,  вы предлагаете создать форк луа и встроить в квик именно форк. Это дорога в ад. Надеюсь, в арке это понимают.
  Мне кажется, с предупреждением, вы опоздали (как всегда, "все украли до нас" :smile: ).
 ARQA уже создала и использует форк луа:
  1) исходники Lua были изменены для обеспечения многопотоковости QLua (смотрите мой комментарий https://forum.quik.ru/messages/forum10/message54696/topic6356/#message54696);
  2) сравните размер кода Lua (~300 кб) с размером кода QLua (более 500 кб).
Отладка QUIK 8.13
 
Цитата
Старатель написал:
Если что-то радикально менять, то это должен быть опциональный вариант.
    Относительно обсуждаемой с вами блокировки потоков:
1. Вы для устранения существующей ошибки QLua предложили хороший вариант нейтрализации этой ошибки на уровне разработчика скриптов (все же, требующий нетривиального анализа и, возможно, дополнительного изменения кода скрипта при каждой его редакции).
2. Есть простая возможность (конкретные изменения в код Qlua, вносимые в течении 30 минут) с использованием идеи вашего предложения, устранить обсуждаемую ошибку в QLua таким образом, что от разработчики скриптов вообще освобождаются от борьбы с обсуждаемой ошибкой. Кроме того, семантика выполнения потоков в QLua становится стандартной (выполнение любого потока, само по себе, не блокирует выполнение других).
3. Мне непонятно, если оставаться в рамках профессионального обсуждения возможных решений, почему вы «топите» за то, чтобы ошибка не исправлялась?
Отладка QUIK 8.13
 
Цитата
Старатель написал:
По моему мнению все "нововведения", которые удаляют или затрудняют работу текущего функционала, только ухудшают "жизнь пользователя".
 Блокировку потоков длинным участком кода пользователя на "чистом" Lua, наверное, трудно назвать функционалом QLua.
Отладка QUIK 8.13
 
Цитата
Старатель написал:
Какие ограничения накладывает отсутствие "Счетчик_для_переключения_State"?
  Некоторое уточнение моих представлений относительно ценности любых средств разработки программ (в том числе QLua).
   Я уже в одном из своих комментариев отмечал:
  что когда обсуждаются любые средства разработки программ, вопрос «нельзя ли это сделать по-другому?» бессмысленен, по той причине, что все можно сделать по-другому. Вопрос по существу может быть таким: «упрощают ли предлагаемые средства разработки программ жизнь пользователя или нет? И в какой степени?».
Отладка QUIK 8.13
 
Цитата
Старатель написал:
Какие ограничения накладывает отсутствие "Счетчик_для_переключения_State"?
     Никакие.  Пользователь анализирует свой код на наличие длинных участков на «чистом» Lua и в «нужных?» местах вставляет вызов какой-нибудь C-функции для переключения_State (с целью исключения блокировки запуска колбенов для других своих скриптов, если они у него есть ( QUIK это позволяет делать)).
---
   Но точно также можно задать похожий вопрос: какие ограничение наложило бы отсутствие в QUIK языка QLua?
   И вот возможный ответ; никакие, все можно написать на  ассемблере.
Работа функций OnStop() и SetCell(), Подвисает скрипт
 
Вариант решения выше озвученных пожеланий:
1) поток, обслуживающий колбеки событий фондового рынка, занимается только ими (и ни чем другим);
2) добавляется отдельный поток запуска/завершения скриптов и обслуживания таблиц QUIK;
3) для защиты потоков от возможной, взаимной блокировки кодами на «чистом» Lua, реализуется решение (состоящее из конкретных правок в 4-х местах исходного текста QLua), которое было приведено в комментарии https://forum.quik.ru/messages/forum10/message56351/topic6356/#message56351
В чем проблемы реализации такого варианта?
В своей системе реализации многопоточных скриптов OS_Quesha я запускаю столько потоков, сколько мне требуется и они работают нормально.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
 
Так как появился QUIK 9.1, то коды и документация OS_Quesha обновлены и в текущий момент времени работоспособны для версий 7<= QUIK <= 9.1: https://cloud.mail.ru/public/2zn2/2tZgedUu4
Отладка QUIK 9.1
 
Поддержка! В архиве https://arqatech.com/ru/support/files/quik-workstation/
  нет кода QUIK Junior v.9.1
Несколько вызовов CreateDataSource
 
Цитата
Виталий написал:
Как я узнаю, что данные заново с сервера скачиваются а не из кэша берутся?
 Какая для вас разница? Косвенный признак того, что есть кеширование, это существенно более быстрый повторный запрос данных и вы это можете проверить. Если клиентов много, то возможно имеет смысл устроить кеширование, если его нет, самому.
Несколько вызовов CreateDataSource
 
Цитата
Виталий написал:
будет ли каждый новый вызов заново требовать данные с сервера?
  Вы это можете проверить сами экспериментально.
Путь к скриптам Lua
 
Цитата
BlaZed написал:
Аа чем getScriptPath() не устраивает?
 Согласен.  Правильнее использовать getScriptPath().
Синхронизация потоков
 
Цитата
Sergey написал:
Прошу помочь в синхронизации потоков.
 В документе разработчика QUIK: «Использование Lua в Рабочем месте QUIK.pdf», в разделе «2. Взаимодействие потоков Lua скрипта» описана рекомендуемая схема обработки колбеков. Если придерживаться ее, то проблем многопоточности (! из-за того, что колбеки запускаются в потоке отличном от потока main) в скрипте пользователя не будет.
 По ссылке https://forum.quik.ru/messages/forum10/message56397/topic6356/#message56397 вы найдете пример из раздела «2. Взаимодействие потоков Lua скрипта».
Путь к скриптам Lua
 
Функция опреlеления папки запускаемого скрипта:

Код
-- Функция определения пути файла запускаемого скрипта ---
 -- Результат: если запуск файла, то путь файла; если строка, то результат nil   ---
function script_path() 
   local str 
   for i = 2, 10000 do  --- поиск корневой функции, вызывающей script_path, начиная с функции в которой вызвана script_path
 --     message (tostring(  debug.getinfo(i) ))
      if  debug.getinfo(i)  then   ---- 
        str = debug.getinfo(i, "S").source
     else
        break
     end
   end

   if  str:sub(1,1) ~= '@' then  ---- ! путь к файлу или имя пакета содержит символ '@'
      return  'Вызов строки'  ---   
   end
   if  not str: find ('\\', 1)  then  --- нет пути к файлу
      return str:sub(2)    --- имя пакета ---
   end
   --  выделение пути файла скрипта ----
   str = str:sub(2) 
   str = str:match('(.*[/\\])') or '.\\'
   str = str: sub(1, #str -1)
   return str
end
Работа функций OnStop() и SetCell(), Подвисает скрипт
 
Цитата
swerg написал:
Сам себя поток прибить не может. Должен кто-то "извне".
Цитата
TGB написал:
Уточнение:  Для случаев зацикливания или блокировок в завершаемом скрипте пользователя, в основном потоке (а лучше, в специальном служебном потоке, чтобы не отвлекать основной поток от обслуживания колбеков, возможно, других работающих скриптов пользователя) контролировать завершение скрипта. Если за время по умолчанию или явно указанное в OnStop() скрипт не завершен, то выполняется принудительное его завершение, но это, скорее всего, будет происходить редко.
-------------------
Цитата
swerg написал:
Это бы развязать, конечно. "Но эт вряд ли".
 На самом деле, устранение обсуждаемых здесь ошибочных ситуаций дело разработчика QUIK. Как это реализовать пусть он решает. Что надо устранить вы описали детально и этого, наверное, достаточно.
Работа функций OnStop() и SetCell(), Подвисает скрипт
 
Цитата
TGB написал:
работу по завершению скрипта пользователя выполнять в потоке main.
 Уточнение:
 Для случаев зацикливания или блокировок в завершаемом скрипте пользователя, в основном потоке (а лучше, в специальном служебном потоке, чтобы не отвлекать основной поток от обслуживания колбеков, возможно, других работающих скриптов пользователя) контролировать завершение скрипта. Если за время по умолчанию или явно указанное в OnStop() скрипт не завершен, то выполняется принудительное его завершение, но это, скорее всего, будет происходить редко.
Работа функций OnStop() и SetCell(), Подвисает скрипт
 
Цитата
swerg написал:
Это явная ошибка, которую необходимо исправить.Да, обработчики событий не должны вызываться после OnStop, в этом есть логика, да и это явно описано в документации. Но другие-то функции взаимодействия с терминалом почему не должны работать?? потому что "так получилось"? Нет уж, это не есть обоснование; это лишь признание кривоватой реализации данного места, которая, очевидно, является ошибкой и должна быть исправлена.
 Присоединяюсь к коллеге.
1. Непонятно, почему таблицы QUIK обслуживаются в основном потоке обработки колбеков. В чем проблема сделать обслуживание таблиц QUIK в отдельном специальном для этого потоке?
2. Зачем завершение скрипта пользователя выполняется в потоке обработки колбеков? Наверное, в OnStop() было бы достаточно выставлять признак завершения скрипта, а все работу по завершению скрипта пользователя выполнять в потоке main.
Отладка QUIK 8.13
 
Цитата
Старатель написал:
Держите и вы от меня "шайбу":
     Есть все-таки большая разница между «шайбами»:
1) перешел один раз на схему, рекомендуемую разработчиком QUIK, и далее проблемами конфликтов с основным потоком запуска колбеков не заморачиваешся;
2) всякий раз при изменении/добавления кода скрипта анализируй участки кода на предмет его потокобезопасности да еще и вставляй прокладки для защиты от блокировок.
Отладка QUIK 8.13
 
Цитата
Старатель написал:
как  вариант , или многоуровневые таблицы, или одно событие может менять состояние нескольких таблиц...

 Любой существующий скрипт, в котором нет очереди  между вызовами колбеков и их обработкой, легко может быть преобразован в вариант скрипта, схема работы с колбеками которого, описана в разделе «2. Взаимодействие потоков Lua скрипта». Поэтому никаких функциональных ограничений данной схемой не накладывается. При этом, так как работа с очередями потокобезопасна, а вся остальная обработка выполняется только в main, то никаких конфликтов скрипта пользователя с основным потоком вызова колбеков не может быть.
-------------------------------------------
  Из раздела «2. Взаимодействие потоков Lua скрипта».

Пример реализации очереди FIFO («первым пришёл — первым ушёл») для обработки
срабатывания функций обратного вызова в функции main():
Код

function OnInit(script)
 is_run = true
 MAIN_QUEUE = {}
end

function OnOrder(order)
table.sinsert(MAIN_QUEUE, {callback = "OnOrder", value = order})
end

function OnTrade(trade)
   table.sinsert (MAIN_QUEUE, {callback = "OnTrade", value = trade})
end

function OnAllTrade(all_trade)
table.sinsert(MAIN_QUEUE, {callback = "OnAllTrade", value = all_trade})
end

function OnQuote(class_code, sec_code)
local quote = getQuoteLevel2(class_code, sec_code)
table.sinsert(MAIN_QUEUE, {callback = "OnQuote", value = quote})
end

function OnStop()
is_run = false
return 2000
end

function main()
  while is_run do
    if #MAIN_QUEUE > 0 then
       ProcessingCallbakc(MAIN_QUEUE[1])
       table.sremove(MAIN_QUEUE, 1)
       message("Размер очереди " .. tostring(#MAIN_QUEUE))
    end
 end
end

function ProcessingCallbakc(value)
  message(string.format("Обработка события %s начата", value.callback))
  sleep(3000) --эмуляция продолжительного алгоритма обработки события
  message(string.format("Обработка события %s завершена", value.callback))
end
Отладка QUIK 8.13
 
Цитата
Старатель написал:
Иногда в скрипте требуется что-то большее, чем просто в одном потоке засунуть значение в табличку и вытащить его в другом.
 Какие ограничения накладывает рекомендуемая разработчиком QUIK схема обработки колбеков на обработку данных в скрипте пользователя?
Отладка QUIK 8.13
 
Цитата
Старатель написал:
Это позволяет скриптеру писать байткод-циклы (в текущей версии QLua 5.3/5.4), выполняющиеся атомарно (читай потокобезопасно).
 При реализации вашего пожелания на уровне QLua скриптер лишится такой возможности.
--
 В документе разработчика QUIK: «Использование Lua в Рабочем месте QUIK.pdf», в разделе «2. Взаимодействие потоков Lua скрипта» описана рекомендуемая схема обработки колбеков. Если придерживаться ее, то проблем многопоточности (! из-за основного потока обработки колбеков) в скрипте пользователя не будет вообще: ни в «чистом» Lua-коде ни в смешанном.
Отладка QUIK 8.13
 
Цитата
Roman Azarov написал:
27.04.2021 06:18:12
TGB , добрый день!Оба пожелания зарегистрированы, мы постараемся их рассмотреть. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожеланий в будущих версиях ПО.Каких-либо сроков назвать не можем. Как будет результат анализа пожеланий, мы сообщим Вам в данной теме.
  Прошло два месяца.
Просьба к поддержки: сообщить результаты рассмотрения пожеланий.
----
 Второе пожелание факультатив и, наверное, его стоит рассматривать после устранения критических ошибок, но первое пожелание (было отмечено сразу при описании пожеланий) это устранение ошибки.
 Напоминаю:
  Бывают ситуации зависания в QLua, когда основной поток обслуживания колбеков всех скриптов пользователя, а также таблиц QUIK (это не таблицы Lua), блокируется выполнением  длинного цикла пользовательской программы на «чистом» Lua, в котором нет ни вызова seep ни вызова других C-функций.
 Это может порождать ошибки, которые для многих пользователей QLua (использующих несколько запускаемых скриптов)  являются неожиданными и труднообъяснимыми. Блокируются выполнения колбеков всех скриптов из-за выполнения длинного цикла пользовательской программы на «чистом» Lua в каком-то из запущенных пользователем скриптов.
-----
 Есть простой вариант реализации первого пожелания, кстати, совместимого со вторым  (далее список изменений реализующих этот вариант в в тексте исходни-ков Lua ):
1. В файле   lstate.h  после строки:  lu_byte allowhook;
добавить: int Счетчик_для_переключения_State;
2. В файле   lstate.с  после строки:  L->errfunc = 0;
добавить:  L->Счетчик_для_переключения_State = 0;
3. В файле   lstate.с  после строки:  L1->stacksize = BASIC_STACK_SIZE;
добавить:  L1->Счетчик_для_переключения_State = 0;
4. В файле   lvm.с  после строки:  StkId ra;
добавить:  
if (++L->Счетчик_для_переключения_State > 1000) {   //  1000  надо задать кон-стантой   L->Счетчик_для_переключения_State = 0;
lua_unlock(L); lua_lock(L);
}
------------------------------------  
 В чем проблема реализации первого пожелания?
Отладка QUIK 8.13
 
Я пытаюсь помочь решить наши с вами проблемы потокобезопасности API QLua работы с QUIK.
 Если синхронизация функций API реализована так:
Цитата
TGB написал:
Объекты синхронизации функций API QLua должны локализоваться в месте, общем для всех скриптов пользователя, и это место точно не global_State и тем бо-лее не lua_State. На месте разработчиков QUIK, я бы создал общий для всех скриптов пользователя массив, в котором для каждой функции API QLua выделил элемент хранения объекта синхронизации при работе с этой функцией. Синхронизация должна выполняться не только при обращении к функциям API, но в соответствующих программах, готовящих данные для обсуждаемых функций в потоках отличных от пользовательских.
то тех "плавающих" результатов, которые описаны в ветках:
1) Опять ошибка получения кол-ва ордеров скриптом https://forum.quik.ru/forum10/topic6503/ ;
2) [BUG] getFuturesHolding: ошибка в работе https://forum.quik.ru/forum10/topic6526/ .
по моим представлениям, быть не должно.
 Пусть мне кто-то объяснит, что я ошибаюсь.
Отладка QUIK 8.13
 
Цитата
Roman Azarov написал:
Просьба сделать как с предыдущими пожеланиями, собрать само пожелание (что конкретно, по Вашему, необходимо доработать и каким образом), его актуальность и все комментарии к нему в одном сообщении.Обязательно его зарегистрируем.
   Просьба устранить ошибки, описанные в ветках (там много комментариев и повторять их полностью здесь, наверное не стоит):
1) Опять ошибка получения кол-ва ордеров скриптом https://forum.quik.ru/forum10/topic6503/ ;
2) [BUG] getFuturesHolding: ошибка в работе https://forum.quik.ru/forum10/topic6526/ .
  Ошибки, описанные в упомянутых выше ветках, скорее всего, ошибки синхронизации функций API QLua. И ошибки такого вида, возможно, имеются и в других функциях API.
  Вообще, все функции API работы с QUIK из QLua должны быть потокобезопас-ными  из-за того, что к ним могут обращаться из нескольких одновременно запущенных скриптов (работающих в разных потоках).
     Написанное в упомянутых выше ветках (с приведением кодов и результатов), демонстрирует, что getDepoEx и getFuturesHolding не являются потокобезопасными.
------
    Возможно, то, что написано далее, разработчики QUIK хорошо понимают, но на всякий случай некоторые соображения.
 Объекты синхронизации функций API QLua должны локализоваться в месте, общем для всех скриптов пользователя, и это место точно не global_State и тем бо-лее не lua_State. На месте разработчиков QUIK, я бы создал общий для всех скриптов пользователя массив, в котором для каждой функции API QLua выделил элемент хранения объекта синхронизации при работе с этой функцией. Синхронизация должна выполняться не только при обращении к функциям API, но в соответствующих программах, готовящих данные для обсуждаемых функций в потоках отличных от пользовательских.
Отладка QUIK 8.13
 
Об областях синхронизации.
  Область синхронизации программы это та часть области видимости переменных программы, для которых предполагается обеспечить атомарность (! всей совокупности этих переменных как единого целого) при многопоточной обработки данных.
  Распространенной ошибкой синхронизации в параллельном программировании является неправильное определение области синхронизации. Для эффективности синхронизации ее область должна быть минимальнонеобходимой (однозначно определяющей результат программы), обеспечивающей корректность работы программы. Если область синхронизации программы содержит в себе минимальнонеобходимую, то все будет работать корректно (но не вполне эффективно). Если же область синхронизации не включает в себя минимальноне-обходимую, то это ошибка программы. Поэтому при разработках, в тех случаях, когда не очевидна минимальнонеобходимая область синхронизации, обычно первоначально область синхронизации выбирается с «запасом». Далее эта область, в процессе развития проекта, может быть «сужена», с целью повышения эффективности синхронизации, до минимальнонеобходимой.
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 12 13 След.
Наверх