ещё много много раз - потокобезопасные операции

Страницы: 1 2 След.
RSS
ещё много много раз - потокобезопасные операции, Потокобезопасность.
 
Знаю что много об этом сказано! Знаю что специально сделали потокобезопасные операции с приставкой s или с не важно..
Если сам не специалист в этой области приходится обращаться...
На конкретных примерах ОБЩЕГО вида.
--------------------------------------------
1. это небезопасно!
A={}
function OnAllTrade(alltrade)
       table.insert(A, alltrade)
end

function main()
Table={}
Table=A[1]
end
--------------------------------------------
2. А это безопасно? если нет то почему?

A,B={},{}
function OnAllTrade(alltrade)
       table.insert(A, alltrade)
       B=A
end

function main()
Table={}
Table=B[1]
end
------------------------------------------
3. аналогично?
A=0
function OnAllTrade(alltrade)
       table.insert(A, alltrade)
       A=A+alltrade.price-const_1+const_2+...
end

function main()
C=A/100
if C>const_N then ... end
end
------------------------------------------
4. ....?
A=0
function OnAllTrade(alltrade)
       table.insert(A, alltrade)
       A=A+alltrade.price-const_1+const_2+...
B=A
end

function main()
C=B/100
if C>const_N then ... end
end
----------------------------------------
5. функция getQuoteLevel2(class,sec) и т.п. вставленная внутрь main безопасна, не изменится ли таблица в процессе присваивания(чтения)?
если нет то почему? что такое хэш и в чём отличие от массива?
------------------------------------
6. Прошу, если это возможно, провести маленькую лекцию или дать ссылку где почитать
о работе терминала в плане обработки поступающей информации и взаимодействии скрипта lua с той информацией что поступила в quik. Ясно что вот колбэк он вызывается при изменениях.. НО более подробно в доступной форме, что находится в "чёрном ящике"? Что там за информационные очереди, как они меняются, почему двигаемся по этой очереди, как к этой очереди подвязываются колбэки и main...Вот такого плана... Пожалуйста! Очень прошу, потому как ни чего не понятно...
 
Добрый день.
1 Да, это не безопасно. можете получить что в A[1] == nil

2. Если A и B таблицы, то B=A не копирует содержимое таблиц, а присваивает ссылку на таблицу A в переменную B, и все изменения в A отражаются в B. Далее аналогично п. 1

3 и 4 Примеры не очень понятны. A это таблица или переменная со значением ноль?

5. getQuoteLevel2 всегда возвращает текущий слепок стакана. Что значит "процесс присваивания чтения" не совсем понятно, поясните.
 
2. Я правильно понял что фактически меняя таблицу А я одновременно буду менять B за счёт того что В есть просто ссылка на A.
А если я сделаю пустую операцию над А и приравняю В к этому. Например что то вроде

function copy_(a)
return a
end

function
OnAllTrade(alltrade)
table.insert(A, alltrade)
B=copy_(A)
end

function main()
Table={}
Table=B[1]
end

В 3 и 4 извините поторопился забыл удалить строчку при копировании. Имеются ввиду обычные числовые переменные. Соответственно вроде бы обычные переменные можно то же одновременно модифицировать в колбэке и читать в main()  и вроде может получиться в результате ерунда неизвестного вида. Что мешает этому?

Насколько я понял из старого форума проблема только в table.insert.
Так вот чем table.insert отличается от обычных операций допустим сложения умножения (вроде бы то же модификация). И чем таблицы при модификации отличаются от простых переменных?
 
Приведите пожалуйста потокобезопасные операции, с небольшими пояснениями!
 
Что то я совсем запутался. Следуя вашим словам
B={9,4,3,8}
C=B
таблица C это только ссылка на таблицу B тогда есть разница между записями
а) C[1]=C[1]/2; table.sort(B)
б) table.sort(B); C[1]=C[1]/2
Это так?
И на предыдущие вопросы ответ те  пожалуйста!?
 
Добрый день. В терминале обеспечивается физическая целостность данных. В случае с обычным присвоением a = b проблем нет - вы не сможете получить неопределенное значение переменной a. Либо значение до присвоения, либо после.
В случае с table.insert проблема в том, что это не "атомарная" операция, а целая функция. которая делает следующее:
 
Добрый день.
В терминале обеспечивается физическая целостность данных. В случае с обычным присвоением a = b проблем нет - вы не сможете получить неопределенное значение переменной a. Либо значение до присвоения, либо после.
В случае с table.insert проблема в том, что это не "атомарная" операция, а целая функция, которая делает следующее:
- все элементы с индексом больше либо равным заданному получают индексы на единицу больше;
- указанный элемент вставляется по заданному индексу;
Обращение в момент выполнения функции к элементам таблицы может привести к неопределенной ситуации. Для этого были сделаны потокобезопасные функции - получить доступ к таблице можно лишь после завершения их работы.
 
Цитата
Michael Bulychev пишет:
Для этого были сделаны потокобезопасные функции - получить доступ к таблице можно лишь после завершения их работы.
Поподробнее пожалуйста. Это значит, что при обращении к таблице из другого потока текущая операция будет приостановлена до окончания обновления таблицы?
Надо делать так, как надо. А как не надо - делать не надо.
 
Да, если таблица глобальная.
 
Цитата
Серж пишет:
при обращении к таблице из другого потока текущая операция будет приостановлена до окончания обновления таблицы?
https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D0%BC%D0%B0%D1%84%D0%BE%D1%80_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA­%D0%B0)
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Цитата
s_mike@rambler.ru пишет:
Цитата
Серж пишет:
при обращении к таблице из другого потока текущая операция будет приостановлена до окончания обновления таблицы?
https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D0%BC%D0%B0%D1%84%D0%BE%D1%8 ­0_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D ­0%B8%D0%BA%D0%B0)
400 Bad Request

Цитата
Michael Bulychev пишет:
Да, если таблица глобальная.
Здесь таблица t является глобальной?
Код
local t = {}
function OnAllTrade(alltrade)
  table.sinsert(t, alltrade)
end
function main()
  local t1 = t[1]
end
Будет ли потокобезопасной данная операция?
Надо делать так, как надо. А как не надо - делать не надо.
 
Возможно насчет глобальных я не совсем корректно выразился. Выполнение функции sinsert заблокирует выполнение кода в другом потоке до окончания работы функции.
 
Цитата
Michael Bulychev пишет:
Выполнение функции sinsert заблокирует выполнение кода в другом потоке до окончания работы функции.
Давайте, чтобы не было разночтения сформулируем более точно.
Выполнение функции sinsert заблокирует выполнение кода в другом потоке до окончания работы функции в любом случае или только при обращении из другого потока к таблице, модифицируемой sinsert?
Другими словами, sinsert приостанавливает выполнение другого потока в любом случае или нет?
Надо делать так, как надо. А как не надо - делать не надо.
 
заблокирует/приостановит в любом случае
 
Цитата
Michael Bulychev пишет:
заблокирует/приостановит в любом случае
Понял. Спасибо.
Вы не думаете, что об этом стоило упомянуть в документации?
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Серж пишет:
Вы не думаете, что об этом стоило упомянуть в документации?
Здравствуйте,
Мы рассмотрим этот вопрос
 
хэш - это число.
В луа используется для хранения строковых данных.
В луа таким образом обеспечивается быстрое сравнение строк, так как сравниваются фактически числа.
Кроме того, хранятся лишь уникальные строки, что исключает избыточное хранение копий строк.
 
Цитата
Michael Bulychev пишет:
заблокирует/приостановит в любом случае
Можете изменить алгоритм таким образом, чтобы параллельный поток блокировался только в том случае, если происходит попытка одновременного доступа к модифицируемой таблице?
Надо делать так, как надо. А как не надо - делать не надо.
 
Нет, не можем и не будем этого делать.
За доступом к конкретной таблице пользователь должен следить сам.
 
я так понимаю ввиду того, что может возникнуть взаимоблокировка?
 
Нет, просто нет такого механизма в Lua. за конкретным объектом должен следить сам пользователь.
 
Цитата
Michael Bulychev пишет:
Нет, просто нет такого механизма в Lua.
вы про атомарные операции?
 
Я про существующие средства в языке для многопоточной работы.
 
С колбеками, вроде, понятно: если в колбеке одного скрипта вызывается потокобезопасная функция, то работа основного потока QUIK и дополнительного main этого скрипта "замораживается" на время выполнения функции.
А если потокобезопасная функция вызывается в main, окажет ли это влияние на потоки других скриптов?
Надо делать так, как надо. А как не надо - делать не надо.
 
Любое обращение к глобальным переменным, равно как и любая модификация стека в LUA происходит через критические секции. Исследования показывают, что нет в целом ряде случаев абсолютно никакой выгоды от многопоточности, если не используется соответствующая операционная система и многоядерные процессоры. Широко распространено и подтверждено на практике мнение, что число потоков - должно соответствовать числу ядер. Вот, кстати, статейка на тему: http://www.dtf.ru/articles/print.php?id=39888
 
Цитата
Michael Bulychev пишет:
Выполнение функции sinsert заблокирует выполнение кода в другом потоке до окончания работы функции.
Вообще любого Луа-кода, или заблокирует выполнение только другой потоко-безопасной функции работы с таблицами?

Иначе говоря, рассмотрим приведённый ранее пример:


Код
local t = {}
function OnAllTrade(alltrade)
  table.sinsert(t, alltrade)
end
function main()
  local t1 = t[1]
end
Предположим, что уже начался выполняться оператор
Код
local t1 = t[1]
из main()

И тут вызывается
Код
table.sinsert(t, alltrade)
из OnAllTrade(alltrade)

Это вполне возможно, т.к. это независимые потоки.
Вопрос: table.sinsert() будет ждать завершение выполнения t1 = t[1] или нет?
 
Добрый день.
Это нельзя сказать точно, тут, как говорится кто первый встал...
Важен другой момент - при обычном insert возможна ситуация когда элемент t[1] уже существует, но еще ничем не заполнен. То есть isert это функция в процессе выполнения которой блокировка может случаться и освобождаться неоднократно. При использовании sinsert такого не случится - если элемент t[1] существует (t[1] ~= nil), то и его содержимое уже корректно заполнено.
 
Цитата
Старатель пишет:
С колбеками, вроде, понятно: если в колбеке одного скрипта вызывается потокобезопасная функция, то работа основного потока QUIK и дополнительного main этого скрипта "замораживается" на время выполнения функции.
А если потокобезопасная функция вызывается в main, окажет ли это влияние на потоки других скриптов?
На другие скрипты никак не влияет
 
Цитата
Michael Bulychev пишет:
На другие скрипты никак не влияет
Но пока выполняется потокобезопасная функция основной поток терминала "заморожен", информация с сервера не поступает, колбеки не вызываются. Это вы называете "никак не влияет"?
Надо делать так, как надо. А как не надо - делать не надо.
 
Он и так "заморожен" при выполнении колбека.
 
Michael Bulychev, мне кажется или вы потеряли основную мысль обсуждения?
Цитата
Старатель пишет:
С колбеками, вроде, понятно: если в колбеке одного скрипта вызывается потокобезопасная функция, то работа основного потока QUIK и дополнительного main этого скрипта "замораживается" на время выполнения функции.
А если потокобезопасная функция вызывается в main, окажет ли это влияние на потоки других скриптов?
Надо делать так, как надо. А как не надо - делать не надо.
 
Возможно. Давайте на примерах разбираться.
 
У меня такое ощущение, что это я вам рассказываю, как работает ваш программный продукт. Хотя наоборот было бы гораздо эффективней.

Скрипт 1:
Скрытый текст
Скрипт 2:
Скрытый текст
Запускаем - делаем выводы.
Надо делать так, как надо. А как не надо - делать не надо.
 
Похожего эффекта можно достичь и другими способами, этого мы и не скрывали никогда.
 
Цитата
Michael Bulychev пишет:
этого мы и не скрывали никогда
Цитата
Michael Bulychev пишет:
На другие скрипты никак не влияет
Цитата
Michael Bulychev пишет:
Похожего эффекта можно достичь и другими способами
Какими? (Речь сейчас не идёт про длительную обработку колбека.)
Надо делать так, как надо. А как не надо - делать не надо.
 
замените в скрипте №1 в майне sleep на равносильную задержку в виде цикла.
 
Цитата
Старатель пишет:
Какими? (Речь сейчас не идёт про длительную обработку колбека.)
Для чего мы завели такие функции и чего они позволяют избежать я уже объяснял. В Вашем примере использование ssort совершенно не к месту. Используйте просто sort.  
 
Цитата
sam063rus пишет:
замените в скрипте №1 в майне sleep на равносильную задержку в виде цикла.
Пустого цикла? И? Терминал продолжает получать информацию с сервера, колбеки вызываются.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Michael Bulychev пишет:
Для чего мы завели такие функции и чего они позволяют избежать я уже объяснял. В Вашем примере использование ssort совершенно не к месту. Используйте просто sort.
Вы, наверное, не поняли: это псевдокод. Таким образом, я показал вам, что утверждение
Цитата
Michael Bulychev пишет:
На другие скрипты никак не влияет
не верно. Это говорит о том, что использование потокобезопасных функций оказывает влияние на все запущенные скрипты.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель пишет:
Это говорит о том, что использование потокобезопасных функций оказывает влияние на все запущенные скрипты.
Независимо от потока, в котором они были вызваны.
Надо делать так, как надо. А как не надо - делать не надо.
 
Согласитесь, что пример немного не жизненный?
 
Michael Bulychev,
Прошу Вас, самым детальнейшим образом расписать, как устроено межскриптовое взаимодействие/влияние в QLUA -> интересует:
1. порядок инициализации главной виртуальной машины - > что после чего запускается, как и на каком этапе происходит цикл регистрации и опроса коллбеков.
2. Также прошу расписать в каких случаях создаётся новый lua-thread (имеется ввиду только в обычных скриптах.
3. (несовсем по теме, конечно, но... )
1. в какое место совать свою GUI-билиотеку? в основное тело скрипта,
2. в майн
3. или создавать для этого новый поток ОС и делать в нём свою message-loop бо как диспетчеризация сообщений квиковским главным потоком уже будет не досягаема?
 
Цитата
Michael Bulychev пишет:
Согласитесь, что пример немного не жизненный?
Я что-то не понял, с чем вы спорите? Вы можете привести "жизненный пример", когда использование потокобезопасной функции в одном скрипте "никак не влияет" на другие скрипты?
Надо делать так, как надо. А как не надо - делать не надо.
 
Я не спорю, наоборот соглашаюсь. Про это поведение мы уже рассказывали.
 
ну вот, опять убежал...
 
Цитата
Michael Bulychev пишет:
Нет, просто нет такого механизма в Lua. за конкретным объектом должен следить сам пользователь.
Но в  луа нет ни функций  QLUA,
ни возможности создания функции main в отдельном потоке. - Это все сугубо ноу-хау QUIK.
Может быть,продолжая развитие данного направления,  
сделать необходимые механизмы синхронизации потоков
для всех пользователей?
Я для себя кое-что сделал.
Но некоторые вопросы удобнее решить на стороне терминала .
 
честно сказать, я уже и на майн и на потоки согласен НО! Дайте примеры достойные подражания? А то - документация - никакая, техподдержка, если почитать их сообщения со старого и этого форума и сопоставить (благо MySQL сейчас может пользоваться каждый) друг другу - противоречит, разработчики - привыкли ограничиваться лишь парой фраз. В итоге, как говорится, "вот вам qlua и (ну вы поняли...)". При этом, сотрудники компании ещё сильно обижаются, когда их упрекают в отсутствии знания собственного продукта. Видать, писать, что "проблема будет исправлена в следующей версии" в этой компании уже давно вошло в привычку за 15 лет.
 
хочу привести реальный пример, из жизни. хоть он и несовсем по теме - но главное - суть:
есть 3D-движок CryEngine - от вполне себе современной и раскрученной игры. Причём, он тоже поддерживает LUA. Так вот: чуть покопавшись в его SDK и примерах скриптинга - я чот не нашёл там ни повального использования метатаблиц, ни корутин, ни потоков. Там есть развитая библиотека уже встроенных на уровне движка объектов (Entity). Чтобы наследовать какой-то объект или свойство от другого объекта - там не надо писать полушаманский код на метатаблицах - всё сделано на уровне домохозяек и школьников - хочешь наследовать - вызови пару функций и будет тебе счастье. Насчёт доступа ке глобальным переменным, во многих скриптовых движках - уже давно для этого используют классы, т.е. глобальная переменная - это - тоже класс, причём встроенный в сам движок. Пользователь - вообще в данном случае не думает ни о каких потоках и синхронизации - он просто дёргает методы и навешивает на эту глобальную переменную - события. Список можно бесконечно продолжать.
Хочется ещё раз спросить: для кого эта QLUA - затевалась? Кто целевая аудитория? Какие перспективы? Если всё - это для трейдеров - то это точно не для них, потому как разгребать за вами ваши же огрехи ценою своего счёта по причинам описанным выше - не хватит денег ни у кого. Если это для программистов - то программисты от него тоже - не в восторге. Им было бы куда проще и гибче писать на C++ и не быть ни в чём стеснёнными. Я не спорю, что сама по себе LUA - вполне себе достойный скриптовый язык. НО!!! Вы доведите её уже наконец, до ума, а не выпускайте на рынок вечно-сырой продукт.
 
Уважаемые разработчики, ответьте на такой вопрос:
Является ли запись в файл значений того или иного набора переменных с помощью функции file:write() потокобезопасной?
Иными словами, если в один и тот же файл будет производиться запись в коллбэках (типа OnParam, OnTrade, OnQuote и т.п.), а также в функции main(), то не приведет ли это к каким-то нежелательным или непредсказуемым последствиям?
 
Цитата
Дмитрий пишет:
Уважаемые разработчики, ответьте на такой вопрос:
Является ли запись в файл значений того или иного набора переменных с помощью функции file:write() потокобезопасной?
Иными словами, если в один и тот же файл будет производиться запись в коллбэках (типа OnParam, OnTrade, OnQuote и т.п.), а также в функции main(), то не приведет ли это к каким-то нежелательным или непредсказуемым последствиям?
write не является нашей функцией, это стандартная функция Lua, поэтому, затруднимся дать однозначный ответ.
Попробуйте поискать ответ в сообществе Lua
community
Страницы: 1 2 След.
Читают тему
Наверх