При запусках коллбеков не восстанавливается состояние скрипта по сборке мусора (QUIK 12.2.1.2)

Страницы: 1
RSS
При запусках коллбеков не восстанавливается состояние скрипта по сборке мусора (QUIK 12.2.1.2)
 
В версии QUIK 12.2.1.2 (а, похоже, и в более ранних) при запуске любого коллбека отключается сборка мусора (collectgarbage('stop')), а после его отработки включается (collectgarbage('restart')).  В общем, решение разумное, повышающее надежность, но не сохраняющее состояние сборки мусора скрипта. Это неправильно.
    Надо:
1) сохранять состояние сборки мусора скрипта перед выполнением коллбека;
2) отключать сборку сборку мусора;
3) выполнять коллбек;
4) восстанавливать состояние сборки мусора.
 
В версии QUIK 12.2.2.8 (а, похоже, и в более ранних) при запуске любого коллбека отключается сборка мусора (collectgarbage('stop')), а после его отработки включается (collectgarbage('restart')).  Это ошибка.
   Коллбеки не должны менять состояние уборки мусора после своего выполнения, а должны восстанавливать то, которое было перед их выполнением.
-----
   Разработчик скрипта может в какой-то момент отключить на какое то время уборку мусора (имеет право), а тут прилетает  :smile:  любой коллбек  и все портит.
 
Цитата
TGB написал:
Коллбеки не должны менять состояние уборки мусора после своего выполнения, а должны восстанавливать то, которое было перед их выполнением.
  Поддержка: что не так? Ответьте, пожалуйста.
 
Цитата
TGB написал:
В версии QUIK 12.2.2.8 (а, похоже, и в более ранних) при запуске любого коллбека отключается сборка мусора (collectgarbage('stop')), а после его отработки включается (collectgarbage('restart')).  Это ошибка.    Коллбеки не должны менять состояние уборки мусора после своего выполнения, а должны восстанавливать то, которое было перед их выполнением.
   Вроде, написано понятно, но если непонятно, то демонстрирую кодом:
Код
local OK = false
function OnParam()
   OK = true
end

function main()
   _RUN_ = true
   collectgarbage('stop')     --   Сборка мусора отключена --
   while _RUN_ do
      if not collectgarbage('isrunning') then
         if OnParam and OK then
            message(' Ошибка обработки коллбеков устранена. '
               .. 'В скрипте где то был остановлен сбор мусора. '
               .. 'Вызов коллбека OnParam не меняет состояние сборки мусора', 3)
         end
      end

      sleep(3000)
   end

end

function OnStop()
   _RUN_ = false
   return 10000  
end


   Если код выполняется при подключенном к серверу QUIKе  и при этом нет сообщения:
"Ошибка обработки коллбеков устранена. ............" , то понятно, что коллбек  OnParam включил сборку сборки мусора, отключенную разработчиком в скрипте.
 
TGB,
В качестве гипотезы, могу предположить следующее:
Возможно это связано с тем, что Вы проверяете сборщик в main.
Дело в том, что main - это корутина. В корутине свое адресное пространство для локальных переменных.
Колбек это основная VM там свое.
По логике должны действовать два различных сборщика мусора.
--------------------
Если мое предположение верно, то Вы пытаетесь останавливать один, а проверять другой.
---------------------  
Но я не поверял эту гипотезу, так как меня пока не волнует как работает сборщик в скрипте.  
 
Цитата
nikolz написал:
Дело в том, что main - это корутина.
  С этим согласен.

Цитата
nikolz написал:
В корутине свое адресное пространство для локальных переменных.
  В любых функциях свое адресное пространство для их локальных переменных.

Цитата
nikolz написал:
По логике должны действовать два различных сборщика мусора.
  В Lua один сборщик мусора (вы же смотрели его исходники).

Цитата
nikolz написал:
меня пока не волнует как работает сборщик в скрипте
  Ну, вы не единственный на этом свете  :smile: .
 
Сборщик мусора - это функция и она одна.
Но запускать ее можно с различными стеками VMLua.
-------------
Все функции выполняются в одном стеке.
------------------
Корутина main отличается тем, что для нее выделяется отдельный стенк из стека основной VM.
------------------
Если функцию например колбек вызвать, то ее переменные будут в глобальном стеке основной VMLua.
--------------
Если Вы вызываете функцию в Main, то ее переменные будут в стеке корутины.
------------------------
сборщик мусора собирает мусор в в стеке основном VM.
но при этом он не видит стек коррутины, так как это один объект в основном стеке.
---------------
Но тогда кто освобождает пространство от переменных внутри main?
Я полагаю что делается запуск сборщика для области стека корутины main.
---------------------
 
Цитата
nikolz написал:
сборщик мусора собирает мусор в в стеке основном VM.но при этом он не видит стек коррутины
    Кто вам это рассказал или где вы это прочитали :smile: ?

Цитата
nikolz написал:
Я полагаю что делается запуск сборщика для области стека корутины main.
   Зачем что то предполагать, когда можно узнать точно как это устроено? И для этого на сайте разработчика существуют свободно доступные исходники Lua. Из них вы бы узнали, что управление памятью в Lua общее для всех его стеков и нет специального запуска сборщика для области стека корутины main. В конце концов, можно почитать книгу Р. Иерузалимски.
 
Цитата
TGB написал:
  Надо: 1) сохранять состояние сборки мусора скрипта перед выполнением коллбека;
             2) отключать сборку сборку мусора;
             3) выполнять коллбек;
             4) восстанавливать состояние сборки мусора.
  Если это непонятно, то в переводе на коды это, примерно, следующее (три строки не считая комментариев и пробелов):
Код
     --- Перед выполнением коллбека  ---
     local isrunning = collectgarbage('isrunning')
     if isrunning then collectgarbage('stop') end

         --- Выполнить  коллбек  ---

      --- После выполнения коллбека  ---
     if isrunning then collectgarbage('restart') end
 
Код вызова колбеков наверное не на lua. Надо в C api смотреть: lua_gc(...)
 
Цитата
TGB написал:
collectgarbage('isrunning'
Посмотрите на вызов функций в API C
В качестве параметра в функцию передается указатель на стек.
Когда Вы вызываете сборщик мусора в main, то сборщику будет передан указатель на локальный стек корутины.
Когда вы вызываете сборщик мусора в колбеке, то сборщику передается указатель на глобальный стек основной VM Lua.
----------------
Т е в каком стеке Вы вызовите сборщик, тот стек он и будет чистить.
 
Цитата
nikolz написал:
Т е в каком стеке Вы вызовите сборщик, тот стек он и будет чистить.
 
Цитата
TGB написал:
В конце концов, можно почитать книгу Р. Иерузалимски
 Вы умеете читать? Или только пишите  :smile: ?
Цитата из книги 32.2 Сборщик мусора: "Фаза очистки обходит все объекты Lua."  Вы понимаете, что в Lua объектами являются и его стеки?  В конце концов, детали сборки мусора вы можете посмотреть в исходниках Lua.
 
nikolz забыл вас спросить: вы понимаете почему разработчики QUIK при выполнении коллбеков останавливают сборку мусора?
 
Цитата
nikolz написал:

Т е в каком стеке Вы вызовите сборщик, тот стек он и будет чистить.
Динамическая память - это не стек. Или имелся ввиду поток? Ну мы же можем передавать объекты между потоками. Не может быть разделения по потокам для сборки мусора.
Цитата
Each Lua state has one or more threads, which correspond to independent, cooperative lines of execution. The type lua_State (despite its name) refers to a thread. (Indirectly, through the thread, it also refers to the Lua state associated to the thread.)  
Страницы: 1
Читают тему
Наверх