funduk написал: Вы имеете ввиду что-то, отличное от Lua команды dofile?
Я имею ввиду - "Возможно ли с помощью одного Lua скрипта, запустить другой ?" То есть один Kua скрипт запущенный в цикле проверял бы если другой Lua скрипт не запущен - то запустить его.
Разбираясь в работе Quik и функциональных возможностях Lua, иногда можно запутаться, и тогда трезвый взгляд со стороны помогает всё расставить по местам. Для меня таким взглядом всегда был Nikolay. И сейчас я бы не стал вмешиваться в эту дискуссию, если бы не ответы!
Да, это возможно! В Lua действительно можно запустить другой Lua-скрипт с помощью функций dofile или loadfile. Вы можете создать основной скрипт, который будет проверять, запущен ли другой скрипт, и если нет — запускать его. Все это и так явно.
Но почему бы не пойти дальше? Хочу озвучить другой подход.
Давайте забудем про все языки (Си, C#, да и про Fortran с Basic я забыл ещё со студенческих времён). Что у нас есть?
API Quik: разработчики любезно предоставили нам возможность через Lua получать данные от брокера и отправлять приказы (заявки) брокеру.
Функционал Lua: вот здесь начинается самое интересное!
Представим, что поток main — это основной поток (другого ничего нет), в котором всё крутится (в этом легко убедиться, запустив его без задержек). Функционал Lua предоставляет лёгкие потоки, которые работают внутри основного потока — они называются корутины.
Что они делают? Любые программы, блоки, модули, функции — всё это можно запускать в корутинах! Причём не только последовательно, но и асинхронно.
Таким образом, функция main(), будучи запущенной, превращается в сложнейшую программу, способную не только явно но и в фоновом режиме выполнять что угодно: получать данные, проводить расчёты, подключать и останавливать модули и многое другое.
К чему я так подробно рассказываю? Напишите в своей программе модуль на Lua (это та же таблица) который хотите запустить, и используйте его где угодно.
Это открывает огромные возможности для создания гибких и мощных решений.
Есть простой, прямой вопрос - можно ли в окружении терминала выполнить другой скрипт, контролировать его состояние. Ответ - нет. Вы же говорите о том, что давайте вместо поставленной задачи преобразуем её к виду, когда другие скрипты - это модули, выполняющий какие-то действия и контролируемые и выполняемые в окружении скрипта дирижёра. Т.е. по сути - это не отдельные скрипты, а один.
Да, такой подход возможен. Но это не то же самое. Понимая, что прямой вариант невозможен, можно попробовать решить через второй вариант. Но он не всегда применим, т.к. есть скрипты не с открытым кодом, с сложным окружением и т.д. Любители использования dofile могут попробовать запустить так два модуля, использующих переменные с одинаковым именованием.
Т.о. ответ должен быть таким - окружение скрипта, запускаемого в терминале не предоставляет информацию о состоянии других скриптов, не имеет методов запуска/остановки других скриптов, содержащихся в окне списка доступных скриптов LUA терминала.
При этом обмен данными между скриптами сделать можно. А значит существует и третий подход - это иметь два контура в контролируемых скриптах: холостой и рабочий. Тогда скрипт будет отдельной сущностью, его можно отдельно запустить в терминале. Скрипты постоянно работают, но переходят в разные состояния по командам из контролирующего скрипта, через обмен данными. В таком подходе важно обеспечить перехват ошибок, чтобы контролируемый скрипт не "упал". Но опять же - необходимо иметь открытый код скриптов.
Nikolay, Согласен, вопрос составлен не четко, двусмысленно. Но ведь он звучит все таки так:
Цитата
Saturn написал: То есть один Kua скрипт запущенный в цикле проверял бы если другой Lua скрипт не запущен - то запустить его.
Ответ: Да, это возможно. В Lua можно запустить другой Lua-скрипт с помощью функции dofile или loadfile. Вы можете создать основной скрипт, который будет проверять, запущен ли другой скрипт, и если нет, то запускать его. Вот такого подхода пример:
Код
-- основной скрипт (main.lua)
local is_other_script_running = false
-- Функция для проверки, запущен ли другой скрипт
function check_if_other_script_running()
-- Здесь можно реализовать проверку, например, через файл или глобальную переменную
-- В данном примере просто используем переменную для демонстрации
return is_other_script_running
end
-- Функция для запуска другого скрипта
function run_other_script()
is_other_script_running = true
dofile("other_script.lua") -- Запуск другого скрипта
is_other_script_running = false
end
-- Основной цикл
while true do
if not check_if_other_script_running() then
print("Другой скрипт не запущен, запускаю...")
run_other_script()
else
print("Другой скрипт уже запущен.")
end
-- Пауза перед следующей проверкой
os.execute("sleep 1") -- Для Linux/MacOS
-- os.execute("timeout /t 1") -- Для Windows
end
Никаких принципиальных сложностей. В этом примере: Основной скрипт (main.lua) работает в бесконечном цикле. Он проверяет, запущен ли другой скрипт (other_script.lua), с помощью функции check_if_other_script_running. Если другой скрипт не запущен, он запускает его с помощью dofile("other_script.lua"). После завершения работы другого скрипта, флаг is_other_script_running сбрасывается.
Вы поднимаете более сложный вопрос, о взаимодействии между скриптами в окружении терминала, в контексте Lua. И отвечаете, прямое управление скриптами в терминале невозможно, но есть обходные пути.
Saturn написал: Возможно ли с помощью одного скрипта запустить другой ?
Полагаю, что вопрос не о запуске lua функций из файлов, а именно скриптов QUIK на основе библиотеки QLua так как это две большие разницы. ------------------------ Запуск функций из файлов с помощью dofile в вызывающем их потоке. Т е сколько бы функций не запустили будет основной поток с колбеками и поток main. ------------------------- При запуске скриптов QUIK будет создаваться новый поток main. Таким способом можно запустить столько потоков сколько хочется. ------------------------------ Сделать это можно.
Ну вы конечно очень глубоко копнули, а человек спросил просто можно ли одним скриптом в окне "доступные скрипты" перевести второй скрипт из состояния "остановлен" в состояние "запущен".
Штатными средствами сделать этого нельзя. Понятно что имея возможность запускать любой код в подключаемых библиотеках можно сделать вообще все что угодно, однако это не будет хорошим решением.
Станислав написал: Ну вы конечно очень глубоко копнули, а человек спросил просто можно ли одним скриптом в окне "доступные скрипты" перевести второй скрипт из состояния "остановлен" в состояние "запущен".
Штатными средствами сделать этого нельзя. Понятно что имея возможность запускать любой код в подключаемых библиотеках можно сделать вообще все что угодно , однако это не будет хорошим решением.
Задача решается с помощью механизма Event (ранее об этом говорил как альтернатива использования sleep в main).
И еще... Нет смысла запускать скрипты с помощью dofile (особенно как в приведенном VPM примере) Так как это лишь замедляет исполнение. --------------- dofile имеет смысл применять для разделения большого скрипта на блоки, чтобы упростить чтение и отладку скрипта.
nikolz написал: И еще...Нет смысла запускать скрипты с помощью dofile (особенно как в приведенном VPM примере)Так как это лишь замедляет исполнение.---------------dofile имеет смысл применять для разделения большого скрипта на блоки, чтобы упростить чтение и отладку скрипта.
nikolz, Пример выше это просто демонстрация возможностей, ни на что не претендующая. К примеру у себя использую следующий вариант (кусочек из рабочего код):
Код
-- Пытаемся загрузить библиотеку
local fuzzy;
local success, err = pcall(dofile, path..'\\luafuzzy.lua')
if not success then
Log:error("Ошибка при загрузке файла luafuzzy: " .. err)
else
-- Если библиотека успешно загружена, используем её
local fuzzy = luafuzzy()
Log:info("Библиотека luafuzzy успешно загружена!")
end
while WORKING_FLAG do
Перед основным циклом while WORKING_FLAG do 1 раз вызываем "Пан или пропал!" , ни чего не замедляем, просто Функция dofile выполнит Lua-скрипт, и все переменные и функции, определённые в нём, будут доступны в текущем окружении. И смысл здесь в подключении новой задачи!
nikolz написал: И еще...Нет смысла запускать скрипты с помощью dofile (особенно как в приведенном VPM примере)Так как это лишь замедляет исполнение.---------------dofile имеет смысл применять для разделения большого скрипта на блоки, чтобы упростить чтение и отладку скрипта.
nikolz, Пример выше это просто демонстрация возможностей, ни на что не претендующая. К примеру у себя использую следующий вариант (кусочек из рабочего код):
Код
-- Пытаемся загрузить библиотеку
local fuzzy;
local success, err = pcall(dofile, path .. '\\luafuzzy.lua')
if not success then
Log:error( "Ошибка при загрузке файла luafuzzy: " .. err)
else
-- Если библиотека успешно загружена, используем её
local fuzzy = luafuzzy()
Log:info( "Библиотека luafuzzy успешно загружена!" )
end
while WORKING_FLAG do
Перед основным циклом while WORKING_FLAG do 1 раз вызываем "Пан или пропал!" :: , ни чего не замедляем, просто Функция dofile выполнит Lua-скрипт, и все переменные и функции, определённые в нём, будут доступны в текущем окружении. И смысл здесь в подключении новой задачи!
Вообще-то загрузка библиотеки и запуск скрипта в вашем примере это две большие разницы. Поясняю. Загрузка библиотек делается как правило один раз при запуске скрипта. Это необходимая операция, так как библиотек много разных и разумно не изобретать велосипед, а использовать готовый. Так как загрузка изначально и однократно, то не имеет значение время загрузки. ----------------------- В вашем примере Вы грузите и запускаете скрипт не однократно, так как используете флаг загрузки. Но нет смысла грузить и запускать скрипт т. е. многократно его грузить. Я через dofile загружаю свои библиотеки функций с целью разделить большой скрипт на части и отлаживать эти части отдельно. Фактически это вариант создания библиотеки, с упрощением обмена данными через глобальный стек.
nikolz, Да Вы совершено правы, я лишь хотел подчеркнуть особенность подключения
Цитата
VPM написал: Функция dofile выполнит Lua-скрипт, и все переменные и функции, определённые в нём, будут доступны в текущем окружении. И смысл здесь в подключении новой задачи!
Ведь есть еще способ local Utility = require("Utility").
VPM написал: nikolz, Да Вы совершено правы, я лишь хотел подчеркнуть особенность подключения
Цитата
VPM написал: Функция dofile выполнит Lua-скрипт, и все переменные и функции, определённые в нём, будут доступны в текущем окружении. И смысл здесь в подключении новой задачи!
Ведь есть еще способ local Utility = require("Utility").
require - это способ подключения готовых (не собственных) библиотек в том числе на С. Но при этом вы не можете передать в из них данные через глобальный стек. ------------------- Повторю свое мнение. dofile -не для подключения новой задачи, а для разделения длинного скрипта на отдельные куски, чтобы было проще читать и отлаживать. --------------------- Аналогия на книжках примерно такая: подключение библиотек с помощью require - это как сборка коллекции различных книг. а применение dofile - это как сборка книжки их листов.