Функция main выполняется в отдельном потоке, в этом весь смысл, чтобы его понять лучше, запустите вот такой скрипт:
1
2
3
| while true do
sleep(10000)
end |
while true do
sleep(10000)
end
Попробуйте что-то сделать в терминале после запуска такого скрипта. Ваш терминал будет «висеть» 10 секунд, потому что цикл while будет выполняться в основном потоке терминала, в том же где происходит все взаимодействие с пользователем, т.е. с Вами.
Потом запустите вот такой скрипт:
1
2
3
4
5
| function main()
while true do
sleep(10000)
end
end |
function main()
while true do
sleep(10000)
end
end
Здесь тот же самый цикл, только уже внутри main, после запуска такого скрипта терминал будет работать как обычно, как будто никакого скрипта и не выполняется, потому что для функции main терминал создаст отдельный поток, параллельный основному. Чтобы понять что такое потоки, можете сравнить их с рабочими на фабрике, один рабочий — один поток. Представьте, что у Вас есть один рабочий, который занимается отрисовкой всего в терминале, он все отрисовывает, все работает, все хорошо. И тут Вы ему говорите: «Выполни мой скрипт», он говорит: «Хорошо», бросает отрисовку, начинает выполнять Ваш скрипт и видит там команду sleep(10000), для него это означает «ничего не делай 10 секунд», он говорит: «хорошо», и просто сидит на стуле 10 секунд 🙂 Естественно никто в это время ничего в терминале не перерисовывает и не реагирует на действия пользователя. Посидел работник 10 секунд и дальше продолжил заниматься отрисовкой, терминал «ожил». А вот если Вы ему «скажите» выполнить второй скрипт с main, то он, увидев main, подзывает другого работника, который ничего не делал и перекладывает эту задачу на него, а сам продолжает заниматься отрисовкой, т.к. наш первый работник у них главный, он может другим задачи распределять 🙂 Второй работник начинает выполнять все, что находится в функции main и никак не отвлекает «бригадира» от его работы.
Сразу могу провести аналогию с функциями обратного вызова. Если, например, мы запустили такой скрипт:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| run = true
function main()
while run do
sleep(10)
end
message('Пока')
end
function OnTrade()
message('Появилась новая сделка')
end
function OnStop()
run = false
end |
run = true
function main()
while run do
sleep(10)
end
message('Пока')
end
function OnTrade()
message('Появилась новая сделка')
end
function OnStop()
run = false
end
«Бригадир» смотрит что в нем сверху вниз, видит run = true, записывает себе в журнал, что в таком-то скрипте есть переменная run и она равна true, смотрит дальше, есть функция main, значит нужно будет привлечь другого работника, смотрит дальше, и видит функцию обратного вызова OnTrade, а в должностной инструкции бригадира написано, что это его обязанность обрабатывать функции обратного вызова, он у себя помечает в журнале, что когда придет информация о сделке пользователя, он должен выполнить эту функцию в этом скрипте, смотрит дальше, и видит что есть, так же, функция обратного вызова OnStop, опять помечает у себя в журнале, что если пользователь нажмет кнопку «Остановить» выделив перед этим данный скрипт в окне «Доступные скрипты», то он должен выполнить эту функцию . После этого он, как обычно, подзывает работника, говорит ему выполнять main и продолжает заниматься своей работой по обслуживанию терминала. Работник начинает выполнять то, что в main, смотрит, а в ней цикл «ПОКА(while) переменная run равна true ДЕЛАТЬ(do) «, проверяет переменную run, а она действительно равна true, и начинает делать то, что внутри цикла написано, видит там паузу 10 миллисекунд, ничего не делает 10 мс, идет дальше, видит там end, значит конец цикла, но так как это цикл, то он возвращается обратно к while и снова проверяет значение переменной run, оно по прежнему true и он опять выполняет паузу, и будет продолжать так делать, пока(while) переменная run равна true.
А в это время в терминал приходит информация, что по выставленной пользователем ранее заявке совершилась сделка, бригадир, получив эту информацию, смотрит свой журнал и видит, что при таком событии он должен выполнить функцию OnTrade в нашем скрипте, что он и делает, видит, что он должен вывести сообщение с текстом «Появилась новая сделка», делает это и продолжает заниматься своей работой. Сделок может быть много и каждый раз он будет выводить сообщение.
Потом вдруг нам надоело получать эти сообщения о сделках и мы нажали кнопку «Остановить» для этого скрипта. Бригадир опять читает свой журнал и видит, что должен выполнить функцию OnStop прежде, чем завершить наш скрипт. Переходит к ее выполнению, смотрит, а там написано, что он должен переменной run присвоить значение false, что он и делает, а так же ставит себе таймер на 5 секунд, после срабатывания которого он должен работнику, который выполняет main дать приказ завершить все работы и исчезнуть куда-нибудь, если он сам не придет в течении этих 5 секунд и не скажет, что он все выполнил 🙂
А в это время работник, в очередной раз проверяя значение переменной run, обнаруживает, что она уже не равна больше true, а равна false, а значит не нужно больше выполнять цикл, он переходит к тому, что ниже цикла, видит, что должен вывести сообщение с текстом «Пока», делает это, смотрит дальше, а дальше конец функции main, а значит и конец его работы. Радостный он бежит к бригадиру, сообщает, что все сделал, бригадир отпускает его с работы домой, а у себя из журнала вычеркивает переменную run и функции OnTrade и OnStop, после чего продолжает заниматься своей работой, как будто этого скрипта никогда и не было 🙂