main()

Страницы: 1
RSS
main()
 
Подскажите:

1. В main() можно использовать функции получения данных от Квика, которые обычно используются в колбаках? Такие как getParamEx(), getLevel2Quotes() и т.д.

2. QLua нормально синхронизирует обращение к переменным, помеченным как local, если к ним идет доступ и из потока колбаков, и из потока main?
 
1. Эти функции в первую очередь предназначены для использования внутри main(). В колбеках их можно использовать, но идеологически это неправильно.

2. синхронизация на уровне оператора присваивания значений переменным синхронизирована. Глобальная или локальная переменная - разницы нет. Проблемы с синхронизацией обычно начинаются при попытках одновременно изменять поля таблиц из колбеков и main(). Потом окажется, что не все стандартные функции потокобезопасны. Этот список вы потом дополните сами.
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Цитата
Constantin написал:
Подскажите:

1. В main() можно использовать функции получения данных от Квика, которые обычно используются в колбаках? Такие как getParamEx(), getLevel2Quotes() и т.д.

2. QLua нормально синхронизирует обращение к переменным, помеченным как local, если к ним идет доступ и из потока колбаков, и из потока main?
main и колбеки имеют общий глобальный стек VMLua.
Поэтому есть синхронизация обращения к глобальным пере5менным.
Кроме того, обращение к глобальным переменным в кобеке приводит к блокировке main при обращении к этим же переменным.
Т е колбеки и main в этой ситуации работают последовательно.
--------------------
локальные стеки у них разные. поэтому синхронизация не требуется ,
так как вы не сможете обратиться к локальным переменным майн из колбека и наоборот.
 
Цитата
nikolz написал:
так как вы не сможете обратиться к локальным переменным майн из колбека и наоборот.
Так "глобальная" переменная, объявленная с local вне функций, захватывается разными функциями и становится для них "локальной".  
 
Цитата
Constantin написал:
Цитата
nikolz написал:
так как вы не сможете обратиться к локальным переменным майн из колбека и наоборот.
Так "глобальная" переменная, объявленная с local вне функций, захватывается разными функциями и становится для них "локальной".  
Вы это сами придумали или где прочитали?
Вы хотя бы поняли, что написали?
-----------------------------------------------
Если Вы локальной переменной присваиваете значение глобальной,
то будет выполнено копирование  значения для скалярной величины и копирование указателя для таблицы.
--------------------
Поэтому никто ничего не захватывает и ничем не становится.  
 
nikolz

Так захват переменной, он же closure.
 
Цитата
Constantin написал:
nikolz

Так захват переменной, он же closure.
это вообще не о том.
-------------
Объясняю...
--------------
Если функции передается значение скалярной переменной, то
при входе внутрь функций луа всегда происходит создание копии скалярной переменной.
В отличии от СИ, в луа нельзя передать указатель на скаляр.
-----------------
Т е если  Вы присваиваете локальной переменной глобальную, то значение глобальной копируется в локальную.
-------------------
В этом месте теоретически синхронизация для глобальной переменной нужна,
но так как вы читаете, то эта синхронизация не имеет практического смысла.
----------------------
После этого в локальной переменной у вас копия и никакая синхронизация не требуется,
а изменение локальной не меняет глобальную.
===============  
когда локальной переменной вы присваиваете таблицу
то в локальную записывается указатель  глобальной.
синхронизация опять же будет для глобальной, а не для локальной переменной.
================
Таким образом, в любом случае локальная переменная у Вас недоступна из других потоков и ее синхронизация не требуется.
================
а closure   это сохранение переданного значения функции вне стека функции.
И при новом  входе в функцию эти значения  могут быть использованы.
Но эти значения внутри потока функции и они не доступны по указателю в других потоках.
========================
Поэтому closure - это о сохранении значений внутренних переменных функции при выходе из области видимости этой функции.
читаем документацию:
"замыкание - это функция плюс все, что ей нужно для правильного доступа к своим значениям...
Технически говоря, значение в Lua - это замыкание, а не функция. Сама функция является всего лишь прототипом для замыканий."
===============
 
и еще про closure :
" Внутренняя функция всегда обращается к свободным переменным (которые называют "внешними локальными переменными") косвенно через структуру,
называемую "upval", используя инструкции GETUPVAL и SETUPVAL .
Пока включающая функция активна, upval указывает на слот локальной переменной в стеке
(хотя Lua является виртуальной машиной на основе регистров, она использует стек внутри)
Это удобно, потому что заключающей функции не нужно беспокоиться о том, является ли переменная частью замыкания или нет.
Когда функция возвращается, она копирует локальные переменные в элемент структуры upval и указывает на это upval.
Upval сохраняется до тех пор, пока на него больше никто не ссылается, и в этот момент он может быть собран для сбора мусора.
 
Цитата
nikolz написал:
это вообще не о том.

Да нет. На примере, Stopped.

Вариант 1
Код
Stopped = false

function main()
  while not Stopped do

  end
end

function OnStop()
  Stopped = true
end
Здесь переменная глобальная и обе функции к ней обращаются через _G.

Вариант 2
Код
local Stopped = false

function main()
  while not Stopped do

  end
end

function OnStop()
 Stopped = true
end
Здесь переменная захвачена обеими функциями и доступ к ней идёт через другой механизм. Вот он учитывает, что функции выполняются в разных потоках?
 
Цитата
Constantin написал:
Цитата
nikolz написал:
это вообще не о том.

Да нет. На примере, Stopped.

Вариант 1
Код
  Stopped  =   false 

 function   main ()
   while   not  Stopped  do 

   end 
 end 

 function   OnStop ()
  Stopped  =   true 
 end   
Здесь переменная глобальная и обе функции к ней обращаются через _G.

Вариант 2
Код
   local  Stopped  =   false 

 function   main ()
   while   not  Stopped  do 

   end 
 end 

 function   OnStop ()
 Stopped  =   true 
 end   
Здесь переменная захвачена обеими функциями и доступ к ней идёт через другой механизм. Вот он учитывает, что функции выполняются в разных потоках?
пока это лишь Ваше предположение.
Можете привести доказательство своего предположения?
=================
Я предположу,
что и в первом и во втором случае используется глобальный стек.
---------------------------
Но для хранения локальной общей  переменной создан общий блок в глобальном стеке.
---------------------------
Т к указатель на локальный стек передается в функцию при ее вызове
В данном случае никаких вызовов при создании данной переменной нет.
-----------------------------------
И уж тем более - этот никакой не захват,
в классическом понимании этого механизма ,
так как он реализуется внутри функций,
а в данном случае - это классическая глобальная переменная.
------------------------
если будет настроение напишу тест .
 
Constantin,
Вы неправильно понимаете механизм замыкания.
Ваш пример
Код
local Stopped = false

function main()
  while not Stopped do

  end
end

function OnStop()
 Stopped = true
end

не является замыканием, так как при выходе из функции, значение Stopped не сохраняется в ней для последующего использования.
Это глобальная переменная и она может быть изменена вне функции, что у Вас и делается.
----------------------
Пример замыкания Вы можете изучить в скриптах индикаторов, которые предлагаются разработчиками  КВИК.
Например этот:
Код
function AD() --Accumulation/Distribution ("AD")
   local tmp = {pp=nil, p=nil}
   local it = {p=0, l=0}
return function (I, Fsettings, ds)
   if I == 1 then
      tmp = {pp=nil, p=nil}
      it = {p=0, l=0}
   end
   if CandleExist(I,ds) then
      if I~=it.p then 
         it={p=I, l=it.l+1}
         tmp.pp = tmp.p
      end
      local CLH=(2*GetValueEX(it.p,CLOSE,ds)-GetValueEX(it.p,HIGH,ds) - GetValueEX(it.p,LOW,ds))*GetValueEX(it.p,VOLUME,ds)
      local HL=GetValueEX(it.p,HIGH,ds) - GetValueEX(it.p,LOW,ds)
      if HL==0 then 
         tmp.p = tmp.pp or 0
      else
         tmp.p = CLH/HL + (tmp.pp or 0)
      end
      if it.l==1 then
         if HL == 0 then return 0
         else return CLH/HL end
      else
         return tmp.p
      end
   end
return nil
end
end
это замыкание:
Код
   local tmp = {pp=nil, p=nil}
   local it = {p=0, l=0}
return function (I, Fsettings, ds)
 

Замыкание — это особый вид функции.
Она определена в теле другой функции и создаётся каждый раз во время её выполнения.
В записи это выглядит как функция, находящаяся целиком в теле другой функции.
При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции.
Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции.
Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде).
Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён.
От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.
-------------------------
https://www.sbup.com/wiki/Замыкание_(программирование)


 
Цитата
nikolz написал:
Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде). Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.
Правильно. Всё тело файла кода, в луа, считается chunk. Переменные, помечены как local внутри chunk, захватываются функциями, когда эти функции определяются в chunk, и эти переменные разделяются между ними.

На этом все.
 
Цитата
Constantin написал:
Цитата
nikolz написал:
Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде). Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.
Правильно. Всё тело файла кода, в луа, считается chunk. Переменные, помечены как local внутри chunk, захватываются функциями, когда эти функции определяются в chunk, и эти переменные разделяются между ними.

На этом все.
Т е согласны, что ваш пример не про захват, а про глобальную переменную.
Ничто ничего не захватывает, в буквальном смысле как Вы это понимаете.
А создается копия.
Поэтому локальная переменная сохраняет значение глобальной и не зависит от изменения глобальной, если это скаляр
а если это таблица то хранит ссылку на глобальную переменную, а не ее значение, а ссылка тоже не изменяется.
в итогу локальная переменная не изменяется при изменении глобальной
и синхронизация нужна лишь для глобальной.
 
По-моему, в этой ветке смешались разные смыслы слова "захват".
1. Захват как контекст, как обрасть видимости, как closure
2. Захват как блокировка обращения к одной области памяти разными потоками.

Про 2
Не важно как вы определили переменную, поступ и изменение её потокобезопасно в смысле структур Lua, в смысле корректности состояния переменной.
Если тут возникают проблемы и состояние переменной становится невалидным, то это однозначно ошибка QLua и её исправят.

Про 1
Это чисто семантмческие моменты языка Lua, и, насколько я понял первое сообщение, вопрос совсем не про это.
 
Цитата
swerg написал:
По-моему, в этой ветке смешались разные смыслы слова "захват".
1. Захват как контекст, как обрасть видимости, как closure
2. Захват как блокировка обращения к одной области памяти разными потоками.

Про 2
Не важно как вы определили переменную, поступ и изменение её потокобезопасно в смысле структур Lua, в смысле корректности состояния переменной.
Если тут возникают проблемы и состояние переменной становится невалидным, то это однозначно ошибка QLua и её исправят.

Про 1
Это чисто семантмческие моменты языка Lua, и, насколько я понял первое сообщение, вопрос совсем не про это.
мой ответ касался п.2 в вопросе темы.
Мое мнение в том, что QLUA  - это библиотеки функций и в ней нет необходимости синхронизации локальных переменных функций QLUA
т к локальные переменные функций - не являются общими main и колбеков.
-------------------
Мой оппонент привел пример локальной переменной вне функций,
т е это тоже не по теме, но эти локальные переменные являются копией глобальных
и их использование внутри колбеков или функций вне QLUA не требует их синхронизации
т к в них копии глобальных переменных, которые и синхронизируются.  
 
а также указал что closure вообще не причем в вопросе cинхронизации потоков колбеков и майн.
 
Цитата
nikolz написал:
Мой оппонент привел пример локальной переменной вне функций, т е это тоже не по теме, но эти локальные переменные являются копией глобальных
Не являются копией глобальных. Объясняю, что chank оформляется как как функция, после чего выполняться. То есть мой предыдущий пример "компилируется" по смыслу в следующий код:
Код
function init_chank()
  local Stopped = false

  _G["main"] = function()
    while not Stopped do

    end
  end

  _G["OnStop"] = function()
    Stopped = true
  end

end

init_chank()

Страницы: 1
Читают тему
Наверх