Добрый день. Перечитал старый форум, но внятного ответа так и не нашёл. Наверняка уже многие делали то же, что и я, и многие ещё будут делать. Поэтому хочу уточнить один важный момент. Есть Lua - скрипт, в котором подключается своя библиотека на c++. В этой библиотеке создаётся несколько потоков.Например, 1 поток будет отправлять заявки в Quik, другой поток будет читать таблицу параметров, ещё несколько потоков будут подписываться на ТВС и перебирать все сделки через CreateDataSource (а их может быть миллионы). В общем каждый поток будет одновременно запускать какие-то Lua-функции. А Lua - стек у нас только один. Вопрос: нужно ли синхронизировать эти потоки и гарантировать вызов lua функций из dll в одно время только однажды ? Если да, то получается, что пока какой-то поток, например перебирает все сделки в цикле (миллион), то заявки отправлять нельзя ? Параметры читать нельзя ? Все задачи будут ждать завершения какого-то одного потока ? А если нужно одновременно в разных потоках вызвать CreateDataSource, каждый со своим инструментом, и одновременно их записывать в какие-либо массивы ?
Пользователь
Сообщений: Регистрация: 01.02.2015
26.02.2015 20:37:02
тема многопоточности, а тем более многопоточности в QLUA - тянет на целую книгу. в одном топике - вам тут никто не ответит на весь список ваших вопросов. Для начала, почитайте вот этот форум: quik2dde.ru. После того, как ВЕСЬ! его прочитаете - прочитайте ещё раза 2.
Цитата
Дмитрий пишет: Перечитал старый форум, но внятного ответа так и не нашёл.
а потому что его и нет))) внятный ответ должны дать Вы сами, бо как изначально, LUA задумывалась, как однопоточная, потом к ней добавили корутины, дочерние состояния (child lua_State) и пр.
Цитата
Дмитрий пишет: Наверняка уже многие делали то же, что и я, и многие ещё будут делать.
увы, таких единицы, если считать, чтоб всё ещё СТАБИЛЬНО работало. Дело в том, что сама QLUA постоянно меняется и постоянно допиливается. поэтому, пока не будет нормальной/стабильной "базы" - все наши "устремления" - лишь жалкие поделки, особенно, принимая во внимание изначальную полную "сопливость" штатной дкументации по QLUA.
Michael Bulychev
Гость
27.02.2015 06:51:05
Цитата
Дмитрий пишет: Добрый день. Перечитал старый форум, но внятного ответа так и не нашёл. Наверняка уже многие делали то же, что и я, и многие ещё будут делать. Поэтому хочу уточнить один важный момент. Есть Lua - скрипт, в котором подключается своя библиотека на c++. В этой библиотеке создаётся несколько потоков.Например, 1 поток будет отправлять заявки в Quik, другой поток будет читать таблицу параметров, ещё несколько потоков будут подписываться на ТВС и перебирать все сделки через CreateDataSource (а их может быть миллионы). В общем каждый поток будет одновременно запускать какие-то Lua-функции. А Lua - стек у нас только один. Вопрос: нужно ли синхронизировать эти потоки и гарантировать вызов lua функций из dll в одно время только однажды ? Если да, то получается, что пока какой-то поток, например перебирает все сделки в цикле (миллион), то заявки отправлять нельзя ? Параметры читать нельзя ? Все задачи будут ждать завершения какого-то одного потока ? А если нужно одновременно в разных потоках вызвать CreateDataSource, каждый со своим инструментом, и одновременно их записывать в какие-либо массивы ?
Добрый день. Я бы настоятельно советовал Вам посмотреть в сторону coroutine в Lua. Уверен, что их возможности полностью покроют описанные Вами задачи. Но если желание наплодить потоков в своей библиотеке непреодолимо, то рекомендации ниже: 1. Линкуйте свою библиотеку с qlua.dll 2. Если пункт два вызывает вопросы, то убедитесь что в папке с терминалом (там же, где лежит info.exe и qlua.dll) присутствует файл lua5.1.dll собранный нами. Проверить это можно в свойствах файла: 3.Для каждого отдельного потока, который работает с Lua перед его запуском необходимо проделать примерно следующее:
4. При завершении работы поток не должен вызывать lua_close(thread_L), это приводит к закрытию всей Lua для скрипта. 5. для того чтобы сборщик мусора при завершении все корректно убрал необходимо сделать:
Код
lua_unref(L, thread_L_ref);
Вроде все. Но я бы все таки настоятельно рекомендовал использовать Lua coroutine
Пользователь
Сообщений: Регистрация: 01.02.2015
27.02.2015 07:29:54
К Вам предложение, дополнить на форуме соответствующие темы, а также написать больше примеров того, как добавлять из C++ новые функции через closure.
Michael Bulychev
Гость
27.02.2015 07:34:24
Цитата
sam063rus пишет: как добавлять из C++ новые функции через closure.
Поясните свою мысль? Для чего это?
Пользователь
Сообщений: Регистрация: 01.02.2015
27.02.2015 07:36:04
но ведь именно так вы регистрируете в qlua свои функции?
получается, если верить Вашим словам - то у Вас должно быть так: #define lua_register(L,n,f) (lua_pushcfunction(L, (getNumberOf)), lua_setglobal(L, ("getNumberOf")))
получается, если верить Вашим словам - то у Вас должно быть так: #define lua_register(L,n,f) (lua_pushcfunction(L, (getNumberOf)), lua_setglobal(L, ("getNumberOf" ;) ))
получается, если верить Вашим словам - то у Вас должно быть так: #define lua_register(L,n,f) (lua_pushcfunction(L, (getNumberOf)), lua_setglobal(L, ("getNumberOf" ;) ))
вот про это я и спрашиваю. Почему именно lua_pushcclosure?
Пользователь
Сообщений: Регистрация: 01.02.2015
27.02.2015 08:32:26
просто для меня понятия: просто функция и closure - несколько различаются.
Michael Bulychev
Гость
27.02.2015 08:47:49
Можно считать, что "обычная" C-функция является частным случаем C closure, у которой нет upvalues.
Пользователь
Сообщений: Регистрация: 01.02.2015
27.02.2015 09:05:06
Цитата
Michael Bulychev пишет: Можно считать, что "обычная" C-функция является частным случаем C closure, у которой нет upvalues.
да. уже прочитал:
Пользователь
Сообщений: Регистрация: 26.02.2015
27.02.2015 10:20:53
Спасибо. Буду думать как лучше сделать.
Пользователь
Сообщений: Регистрация: 03.02.2015
27.02.2015 21:42:46
По поводу *coroutine* вопрос. В руководстве по Люа coroutine описывается как средство создания многопоточной среды. В данном случае многопоточность означает одновременное исполнение в двух потоках или это о другом?
Пользователь
Сообщений: Регистрация: 01.02.2015
27.02.2015 22:25:52
имеется ввиду не потоки операционной сисиемы, а псевдомногопочность на основе LUA. Почитайте здесь:
Пользователь
Сообщений: Регистрация: 30.01.2015
28.02.2015 10:44:57
, 1) Вот здесь: "ещё несколько потоков будут подписываться на ТВС и перебирать все сделки через CreateDataSource (а их может быть миллионы). " У Вас огромные резервы в повышении производительности. Рекомендую полностью пересмотреть Вашу концепцию обработки информации. ----------------------------------------------- 2) Следует учитывать что сораунды не позволяют задействовать множество ядер в процессоре или множество процессоров в кластере. Они позволяют переключаться лишь между фрагментами алгоритма в рамках одного ядра.
Пользователь
Сообщений: Регистрация: 31.01.2015
28.02.2015 11:34:16
lergen, корутины работают по принципу кооперативной многопоточности, то есть пока один поток явно не отдаст управление, другой не продолжит свое выполнение. Фактически работает один поток с переключением на разные точки исполнения программы.
Пользователь
Сообщений: Регистрация: 03.02.2015
01.03.2015 09:36:02
Цитата
Constantin Constantin пишет: lergen , корутины работают по принципу кооперативной многопоточности, то есть пока один поток явно не отдаст управление, другой не продолжит свое выполнение. Фактически работает один поток с переключением на разные точки исполнения программы.
Ок спасибо понятно. Похоже что реально многопоточность можно получить только разделив функции между разными скриптами.
Пользователь
Сообщений: Регистрация: 01.02.2015
01.03.2015 10:25:54
Цитата
lergen пишет: Похоже что реально многопоточность можно получить только разделив функции между разными скриптами.
в самом простом случае - Да.
И даже это нельзя будет назвать истинной многопоточностью - потому что квик работает с одним потоком данных и остальные скрипты просто будут ждать своей очереди для доступа к нему.
Пользователь
Сообщений: Регистрация: 31.01.2015
01.03.2015 11:09:00
Цитата
lergen пишет: Ок спасибо понятно. Похоже что реально многопоточность можно получить только разделив функции между разными скриптами.
Параллельно будет работать только код в main. Все колбаки вызываются в основном потоке Квика.
lergen пишет: Ок спасибо понятно. Похоже что реально многопоточность можно получить только разделив функции между разными скриптами.
Параллельно будет работать только код в main. Все колбаки вызываются в основном потоке Квика.
Ну хотя бы так.
Пользователь
Сообщений: Регистрация: 30.01.2015
02.03.2015 18:19:07
Добрый день, Добавлю свой стакан бензина в костер дискуссии. -------------------------- Есть как минимум два варианта 1) несколько скриптов с обменом информацией между скриптами 2) несколько потоков и один из них main с дополнительной синхронизацией потоков ---------------------------- Хотя поток входных данных с сервера один, но это не мешает сделать параллельную обработку, так как обработка данных умным роботом требует значительных ресурсов. А обработку по разным инструментам можно делать параллельно без проблем. ------------------------------- Из собственного опыта замечу, что в QUIKe на существующем уровне реализуются оба способа( реализовал год назад оба)
Дмитрий пишет: Добрый день. Перечитал старый форум, но внятного ответа так и не нашёл. Наверняка уже многие делали то же, что и я, и многие ещё будут делать. Поэтому хочу уточнить один важный момент. Есть Lua - скрипт, в котором подключается своя библиотека на c++. В этой библиотеке создаётся несколько потоков.Например, 1 поток будет отправлять заявки в Quik, другой поток будет читать таблицу параметров, ещё несколько потоков будут подписываться на ТВС и перебирать все сделки через CreateDataSource (а их может быть миллионы). В общем каждый поток будет одновременно запускать какие-то Lua-функции. А Lua - стек у нас только один. Вопрос: нужно ли синхронизировать эти потоки и гарантировать вызов lua функций из dll в одно время только однажды ? Если да, то получается, что пока какой-то поток, например перебирает все сделки в цикле (миллион), то заявки отправлять нельзя ? Параметры читать нельзя ? Все задачи будут ждать завершения какого-то одного потока ? А если нужно одновременно в разных потоках вызвать CreateDataSource, каждый со своим инструментом, и одновременно их записывать в какие-либо массивы ?
Добрый день. Я бы настоятельно советовал Вам посмотреть в сторону coroutine в Lua. Уверен, что их возможности полностью покроют описанные Вами задачи. Но если желание наплодить потоков в своей библиотеке непреодолимо, то рекомендации ниже: 1. Линкуйте свою библиотеку с qlua.dll 2. Если пункт два вызывает вопросы, то убедитесь что в папке с терминалом (там же, где лежит info.exe и qlua.dll) присутствует файл lua5.1.dll собранный нами. Проверить это можно в свойствах файла:
3.Для каждого отдельного потока, который работает с Lua перед его запуском необходимо проделать примерно следующее:
4. При завершении работы поток не должен вызывать lua_close(thread_L), это приводит к закрытию всей Lua для скрипта. 5. для того чтобы сборщик мусора при завершении все корректно убрал необходимо сделать:
Код
lua_unref(L, thread_L_ref);
Вроде все. Но я бы все таки настоятельно рекомендовал использовать Lua coroutine
А что такое в коде "callbackCode" ? По описанию функции там должен быть lua_State. Какой подставлять - L или thread_L_stack ?
И можно ли при завершении потока делать thread_L_stack в самОм новом-созданном потоке, т.е. внутри функции потока myThread(LPVOID param) ?
Пользователь
Сообщений: Регистрация: 26.02.2015
25.11.2015 15:14:30
В последнем вопросе имелось ввиду: Можно ли при завершении потока делать lua_unref(L, thread_L_ref); в самОм новом-созданном потоке, т.е. внутри функции потока myThread(LPVOID param) ?