не будет вам новостей по одной простой причине: поток новостей стоит для брокеров денег и клиенты не имеют права их транслировать на свои сайты, в телеграм-каналы и так далее.
скорее всего, вы используете какую-то стороннюю lua-библиотеку, которая инициализирует mm-таймер для данного процесса. и он остается до тех пор, пока не перезапустите квик. не обязательно это делается напрямую, может быть связано, например, с проигрыванием аудио.
Sergey Gorokhov написал: Опишите более развернуто что именно Вы хотите получить
например, что-то подобное... LUA:
Код
function threadfunc(...)
while not CuttentThreadTerminated do
--
end
end
thread = CreateThread(threadfunc, ...)
thread.TerminateThread()
thread.Join()
thread = nil
collectgarbage()
вы глупый что ли? мне не нужно вызывать ваши дуструкторы, если я могу просто виртуализировать для вас аллокатор памяти и убить все скопом не разбираясь.
никто. если я запускаю вас в своем сендбоксе, то я тупо уничтожу сендбокс. ровно так как поступает квик при тайм-ауте. делает killthread() и уничтожает luavm.
о-о-о... как все запущено. навскидку знаю несколько способов 1. toolhelp/psapi/whatever 2. виртуализация 3. отладка ... кстати, в lua я решал эту проблему через отладку.
quio написал: Гопода, это тема про ошибки в Квик 8.5, что весьма актуально
эту тему начал я, и арка уже отписалась, что решат проблему после дождичка в четверг. если у вас другая проблема, нежели в 1 сообщении - создайте новую тему, посвященную ей.
Цитата
Anton написал: При чем тут квик, при чем тут луа, в такой форме задача не решается нигде.
так уж нигде? ответ - операционная система. :) если я - хост вашей либы и либа стартанула тред (я, к примеру, знаю, что либа может стартануть тред), то, по факту, я могу.
Anton написал: Если я не умею обрабатывать ошибки в своей либе, то да, мне не надо потоков запускать, и, по-хорошему, вообще библиотек писать не надо, а надо улицы подметать.
ок, раз вы такой гуру... можете сделать библиотеку, которая будет реализовывать одну (две, минимальное количество) функций, которые будут позволять написать что-то вроде:
Код
tlib = require "mylib"
function threadfunc(astr)
message(astr, 1);
while true do
--
end
end
function main()
thread = tlib.CreateThread(threadfunc, "hello, world from thread")
while true do
--
end
end
и попробуйте сделать так, чтобы квик не валился при остановке скрипта, что бы пользователь внутри (хотя бы на lua, оставим за скобкой чужой код в библиотеках) не написал.
не, серьезно, я вас не поддеть хочу. я попытался, у меня вышло средне. если погуглите - найдете даже репу, она MIT.
у вас беда с глазами. изначально темой была ошибка при создании при помощи luaL_newstate(). а питон я вспомнил в контексте перекурочивания lua и превращения его в поделие qlua. попробуйте треды позапускайте в корутинах обычной lua, я на вас посмотрю.
так вы не lua используете, а qlua. считайте другой язык. lua - да, у нее много преимуществ а qlua - совсем другое, это диалект, у нее другие свойства, частичная совместимость...
Anton написал: Верните из OnStop 72 часа и завершайтесь сколько влезет.
простите, я не знал, что сдесь форум специалистов по костылям. вам вопрос "со звездочкой": если другая библиотека, не ваша, выкинула ошибку, спровоцировала панику, куда отправляется ваш способ?
Цитата
новичок написал: lua это про стандарты, оптимальность и контроль
вы это серьезно? луа в квике это про стандарты и контроль? я не ослышался? да половину библиотек нельзя использовать с квиком без ограничений из-за того, что луа в квике нестандартная.
lua машина - принципиально однопоточная, за счет этого она такая быстрая и легкая. то, что ее для квика перелопатили так, чтобы она не валилась при вызове из разных потоков - решение спорное, качество этих доработок неизвестно (ну, точнее, известно, и оно так себе). питон точно такой же расширяемый язык и он от рождения нормально переваривает треды. да, там есть gil, но чтобы lua стала многопоточной, в нее добавили такой же gil, только хуже и сделанный на коленке.
ну, в том, что если квик завершит работу вашего скрипта, то про ваши потоки он ничего не знает, и если они не успели остановиться - то все, привет. можно ухищряться, я делал через и отладку, и через сборщик мусора, но все равно, это невозможно сделать нормально. а, кроме того, это работает только для квика, а не вообще в lua. им нужно было питон встраивать, а не lua, не было бы проблем.
Цитата
quio написал: А если этим потокам нужно взаимодействовать?
подскажите, а для чего вообще вы хотите запускать корутины как треды в lua? это небезопасно и неуправляемо. не лучше ли использовать для этого разные скрипты?
Anton написал: Все ж я исхожу из того, что хотели как лучше
именно по-этому это и сделано так. lua - это все же си библиотека. и расширения, которые для нее пишутся, в основном, подразумевают что все это в стиле си. возможно, хотели сохранить это, мы не узнаем. в любом случае - несовместимый с кодом lua-state - это нечто, что вряд ли можно корректно обработать внутри lua.
Anton написал: Луа ждет лонгджампа, исключение пролетит мимо него и будет поймано уже квиком над луа, то есть вся обработка ошибок луа тупо отключается.
плевать они на это хотели. при завершении скрипта квик извещает программу, ждет 5 секунд, и если тред не завершился, то делает kill и и освобождает занятую lua-vm память. на то, что lua что-то там ждет - плевать. это тот же случай. если это возникло - тупо все стопим и освобождаем, на ошметки плевать. вполне в стиле.
Anton написал: Но самое смешное вот в чем: весь луа таки собран с лонгджампами, теперь это стопроцентно известно, но вот этот довесок кидает исключение, единственное во всей длл.
это, само по себе, не является проблемой. это, что называется, the way things are.
quio написал: "Потокобезопасные функции для работы с таблицами Lua" ссылка именно на qlua.dll
не надо искать тайные смыслы там, где их нет. в первых версиях квика (довольно долго) с поддержкой lua вообще не было никакой lua5.1.dll, а была только qlua.dll. по-этому в доке указана она. хелп просто не меняли.
Цитата
quio написал: Да вот проблема похоже во вновь создаваемых состояниях.
вообще ничего общего. кроме того, то как вы пытаетесь использовать корутины - это зло.
quio написал: Создаю новое состояние через lua_newthread(L), передаю его с свой поток, созданный через _beginthreadex, из этого потока вызываю функцию через lua_call.
это плохая идея. а еще она не имеет ничего общего с, поднятым мной, вопросом арке по поводу конкретного бага.
в дельфи неправильно объявлена lua_version. итого. у нас есть стейт, который передается в luaopen. он 503. мы создаем новый стейт, который тоже оказывается 503. вызываем luaL_openlibs() получаем странное "multiple Lua VMs detected. Expected 5.3 instead of 0.0". очевидно, это не эта ветка:
if (v != lua_version(NULL)) luaL_error(L, "multiple Lua VMs detected");
это может случиться, если L создан не lua53.dll. если мы физически удалим lua5.1.dll, то и не кодом внутри lua5.1.dll. а это значит, что там адский ад какой-то.
ps: очевидно, что код на сайте lua и код, используемый в квике - разный. потому, что сообщение имеет вид "multiple Lua VMs detected. Expected 5.3 instead of 0.0". так, что мы вообще не знаем, что там за код.
Anton написал: _VERSION это как раз глобальная константа, она зашита в длл намертво и всегда такая, какой была при компиляции, чего на нее смотреть. Вот lua_version куда интереснее. Конкретно ошибка "multiple Lua VMs detected" вылезает в результате того, что УКАЗАТЕЛЬ на версию в стейте не равен УКАЗАТЕЛЮ на глобальную версию. На самом деле она не такая и глобальная, статическая переменная внутри самой lua_version(). В каком случае указатель на статическую переменную внутри функции может быть не равен указателю на ту же статическую переменную внутри той же функции? Когда это ДВЕ РАЗНЫХ ФУНКЦИИ. Из разных модулей, например. См. сорцы luaL_checkversion_ и lua_version .
Учим си с Оленем Бобом: 1. lua_version() возвращает G(L)->version; которое есть некое поле внутри приватной структуры L, это поле указатель на double. 2. в luaL_checkversion_() видите там такие звездочки в операции сравнения? это называется разыменование...
Учим lua с Оленем Бобом: 1. _VERSION это никакая не глобальная константа. В языке lua вообще нет констант. Это переменная внутри lua-vm, вот ее инициализация:
/* set global _VERSION */ lua_pushliteral(L, LUA_VERSION); lua_setfield(L, -2, "_VERSION");
и это является аналогом lua_version(), только для скриптов.
Так каким образом lua_version() вернет нам 0.0? Самый простой ответ, в случае, если структура L, или ее части (см. макрос G(L)) имеют другой layout, это может случиться, если версии lua кардинально различаются, например. Но возможны и любые другие варианты.
Далее. Из квика можно полностью удалить lua5.1.dll и квик 8.5 будет нормально работать. но проблема остается.
Все это говорит о том, что ваша теория про "разные модули" не совсем верна.
Anton написал: Дык, насколько понимаю, дело в том, что вы вызываете lua_version() из прилинкованной к вашей длл lua53.dll. Квик до запуска скрипта уже загрузил qlua.dll и запустил машину оттуда, и весь стейт там, а функции из lua53.dll будут работать постольку, поскольку не трогают глобальных переменных луа. Как раз lua_newstate() их трогает, и трогает не те .
забудьте про luaL_newstate(). есть скрипт, который мы запускаем в квике. он считает себя версией 5.3 (message(_VERSION, 1) выдает "Lua 5.3"). дальше require грузит mylib.dll, которая из lua53.dll вызывает lua_version(). результат: 0.0. это ошибка.
и нет никаких "глобальных переменных lua". вся lua инкапсулирована в стейт. luaL_newstate() создает вообще отдельный стейт, который никак не связан с другими стейтами. он будет той версии, которой соответствует вызываемая luaL_newstate(). и для этого создаваемого вами стейта, вы должны использовать функции этой версии. можете попробовать взять generic Lua5.1, создать свою mylib.dll, которая, будучи вызвана из скрипта, загрузит generic либу lua5.3 и создаст стейт 5.3 и запустит в нем что-то еще. у вас все будет работать до тех пор, пока вы для каждого стейта будете использовать его "родное" api. для первого 5.1, для второго 5.3.
Anton написал: Хехе, чудеса. Ошибочка происходит, когда в программе оказываются два луа из разных длл или из экзешника и длл.
вы можете в одном процессе, экзешнике, dll, что угодно, иметь все луа-машины всех версий одновременно. проблемы будут, если вы создадите стейт при помощи одних функций (скажем, из lua5.1.dll), а будете пытаться манипулировать им при помощи других (например, из lua53.dll).
в данном случае, похоже, стейт просто покоррапчен. мусор, возвращаемый lua_version() тому свидетельство.
в квике нет возможности указать, в луа-машине какой версии запускать квик. в luaopen уже передается некий стейт, он должен быть версии 5.3 (или, на худой конец, 5.1). полагаю, что lua5.1.dll - это та же lua 5.3 только захаченная таким образом, чтобы библиотеки пользователей воспринимали ее как 5.1. так вот. если даже ничего в luaopen_ не делать, а вызвать lua_version() из подгруженной lua53.dll, то все равно, результат ее работы никак не должен быть 0.0.
даже еще веселее: lua_version() для инстанса, передаваемого в luaopen_ возвращает значение 0.0 (должна, очевидно, 5.3), а для создаваемого нового инстанса luaL_newstate() - luaversion() возвращает мусорное значение (должна так же возвращать 5.3).
воспроизвести можно так: 1. создаем dll, в ней линкуемся с lua53.dll. 2. в luaopen_... создаем новый инстанс lua vm при помощи luaL_newstate() 3. инициализируем его при помощи luaL_openlibs() получаем исключение "multiple Lua VMs detected. Expected 5.3 instead of 0.0"
что-то вы там не доделали, исправьте, пожалуйста. спасибо.