Добрый день. Перечитал старый форум, но внятного ответа так и не нашёл. Наверняка уже многие делали то же, что и я, и многие ещё будут делать. Поэтому хочу уточнить один важный момент. Есть Lua - скрипт, в котором подключается своя библиотека на c++. В этой библиотеке создаётся несколько потоков.Например, 1 поток будет отправлять заявки в Quik, другой поток будет читать таблицу параметров, ещё несколько потоков будут подписываться на ТВС и перебирать все сделки через CreateDataSource (а их может быть миллионы). В общем каждый поток будет одновременно запускать какие-то Lua-функции. А Lua - стек у нас только один. Вопрос: нужно ли синхронизировать эти потоки и гарантировать вызов lua функций из dll в одно время только однажды ? Если да, то получается, что пока какой-то поток, например перебирает все сделки в цикле (миллион), то заявки отправлять нельзя ? Параметры читать нельзя ? Все задачи будут ждать завершения какого-то одного потока ? А если нужно одновременно в разных потоках вызвать CreateDataSource, каждый со своим инструментом, и одновременно их записывать в какие-либо массивы ?
тема многопоточности, а тем более многопоточности в QLUA - тянет на целую книгу. в одном топике - вам тут никто не ответит на весь список ваших вопросов. Для начала, почитайте вот этот форум: quik2dde.ru. После того, как ВЕСЬ! его прочитаете - прочитайте ещё раза 2.
Цитата
Дмитрий пишет: Перечитал старый форум, но внятного ответа так и не нашёл.
а потому что его и нет))) внятный ответ должны дать Вы сами, бо как изначально, LUA задумывалась, как однопоточная, потом к ней добавили корутины, дочерние состояния (child lua_State) и пр.
Цитата
Дмитрий пишет: Наверняка уже многие делали то же, что и я, и многие ещё будут делать.
увы, таких единицы, если считать, чтоб всё ещё СТАБИЛЬНО работало. Дело в том, что сама QLUA постоянно меняется и постоянно допиливается. поэтому, пока не будет нормальной/стабильной "базы" - все наши "устремления" - лишь жалкие поделки, особенно, принимая во внимание изначальную полную "сопливость" штатной дкументации по QLUA.
Дмитрий пишет: Добрый день. Перечитал старый форум, но внятного ответа так и не нашёл. Наверняка уже многие делали то же, что и я, и многие ещё будут делать. Поэтому хочу уточнить один важный момент. Есть 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
К Вам предложение, дополнить на общеизвестном форуме соответствующие темы, а также написать больше примеров того, как добавлять из C++ новые функции через closure.
получается, если верить Вашим словам - то у Вас должно быть так: #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" ;) ))
По поводу *coroutine* вопрос. В руководстве по Люа coroutine описывается как средство создания многопоточной среды. В данном случае многопоточность означает одновременное исполнение в двух потоках или это о другом?
Дмитрий, 1) Вот здесь: "ещё несколько потоков будут подписываться на ТВС и перебирать все сделки через CreateDataSource (а их может быть миллионы). " У Вас огромные резервы в повышении производительности. Рекомендую полностью пересмотреть Вашу концепцию обработки информации. ----------------------------------------------- 2) Следует учитывать что сораунды не позволяют задействовать множество ядер в процессоре или множество процессоров в кластере. Они позволяют переключаться лишь между фрагментами алгоритма в рамках одного ядра.
lergen, корутины работают по принципу кооперативной многопоточности, то есть пока один поток явно не отдаст управление, другой не продолжит свое выполнение. Фактически работает один поток с переключением на разные точки исполнения программы.
Constantin Constantin пишет: lergen , корутины работают по принципу кооперативной многопоточности, то есть пока один поток явно не отдаст управление, другой не продолжит свое выполнение. Фактически работает один поток с переключением на разные точки исполнения программы.
Ок спасибо понятно. Похоже что реально многопоточность можно получить только разделив функции между разными скриптами.
lergen пишет: Похоже что реально многопоточность можно получить только разделив функции между разными скриптами.
в самом простом случае - Да.
И даже это нельзя будет назвать истинной многопоточностью - потому что квик работает с одним потоком данных и остальные скрипты просто будут ждать своей очереди для доступа к нему.
Добрый день, Добавлю свой стакан бензина в костер дискуссии. -------------------------- Есть как минимум два варианта 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) ?
В последнем вопросе имелось ввиду: Можно ли при завершении потока делать lua_unref(L, thread_L_ref); в самОм новом-созданном потоке, т.е. внутри функции потока myThread(LPVOID param) ?