如何在Lua中的特定日期和特定时间执行全局功能? [英] How do I execute a global function on a specific day at a specific time in Lua?

查看:384
本文介绍了如何在Lua中的特定日期和特定时间执行全局功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Lua编写脚本,该脚本中的许多其他功能将在特定日期的特定时间执行单个循环.当按下一个按钮时,循环开始,思考了一会儿.现在我已经收集到,我将不得不使用os.time来检查系统时间(以毫秒为单位),它也可以以表格形式返回日期,这非常有帮助.我唯一要坚持的是如何表达它,以及是否可能包含os.time的多个定义;因此,在(x)天,将运行loop1,在(y)天,将发生循环2,依此类推.我最有可能把这个复杂化很多……

I'm writing a script in Lua that among many other functions will perform a single loop at a specific time on a specific day. The loop is started when a button is pressed, pondering over this for a while now I have gathered that I will have to check the system time in millis using os.time which in table form can return the date too which is very helpful. The only thing I am stuck with is how to express it, and if it would be possible to include multiple definitions of os.time; so on day (x), loop1 will run and on day (y) loop 2 will occur and so on. I'm most likely over complicating this a lot...

到目前为止,这是我的代码:(当按下按钮时,它崩溃并烧毁)

Here's my code so far: (it crashes and burns when called by the button press)

function runiftime()

day1 = a;
day2 = b;
day3 = c;
day4 = d;
status = 0; -- Default status == 0
target = day4;


-- Where a, b, c & d are shown above I would like different os.time outputs which relate to days in the future an example output of os.time is => = os.time() outputs '1384988715'.

    repeat

 if os.time() == "day1" then

    os.execute("Some command");
    result = Shell.Execute("Some program", "open", "", "",     SW_SHOWNORMAL, false);
    status = 1;
end

 if os.time() == "day2" then

    os.execute("Some command");
    result = Shell.Execute("Some program", "open", "", "", SW_SHOWNORMAL, false);
    status = 1;
end

 if os.time == "day3" then

    os.execute("Some command");
    result = Shell.Execute("Some program", "open", "", "",     SW_SHOWNORMAL, false);
    status = 1;
end

 if os.time == "day4" then

    os.execute("Some command");
    result = Shell.Execute("Some program", "open", "", "",     SW_SHOWNORMAL, false);
    status = 1;
end


    if status == 1 then
        Input.SetText("feed", "Routine Successful!                                  Waiting for Command...");
    else
        Input.SetText("feed", "Automated Routine Started!           Waiting for OS Clock...");
    end

until (os.time == target);  
end

推荐答案

我注意到您的代码存在一些问题.首先,一半时间,您要与os.time(一个函数)和os.time()(一个数字)进行比较.其次,您将进入until (os.time == target);的无限循环,因为os.time除非更改,否则永远不会改变.

I've noticed a few issues with your code. First of all, half the time, you're comparing to os.time which is a function and os.time() which will be a number. Secondly, you're going into an infinite loop with until (os.time == target);, since os.time will never change unless you change it.

即使这样,如果您正确地与os.time()进行比较,也将进入无限循环以检查Lua VM一直在最大程度地消耗CPU使用率的时间,因为不会进行无限循环.这将可能冻结该过程,这可能就是您所说的崩溃和燃烧".

Even then, if you were correctly comparing with os.time(), going into an infinite loop to check the time all the time is going to max out CPU usage for the Lua VM, as infinite loops are wont to do. This will probably freeze up the process, which might be what you mean by "crash and burn."

最后但并非最不重要的一点是,将当前时间与将来的时间与==进行比较通常是一个坏主意,因为条件恰好在准确的期望时间内执行的可能性很小.

Last but not least, comparing the current time to a time in the future with an == is generally a bad idea, due to the low probability of the condition executing precisely during the exact desired time.

我建议您尽可能睡觉,直到准备好执行最早的任务为止.这样,您可以避免在不断轮询的情况下占用不必要的CPU时间.在Lua中,您可以执行以下操作.

I'd recommend sleeping as long as possible until the earliest task is ready to be carried out. This way, you avoid taking up any unnecessary CPU time with constant polling. From Lua, you could do something like this.

local target = os.time{year = 2013, month = 11, day = 21, hour = 9, min = 30}

local function sleep(s) -- wait for `s` seconds
    if type(s) ~= 'number' then
        error's is not a number'
    elseif s < 1 then
      return
    end
    s = math.floor(s)

    -- Windows (delay range limited to 0-9999)
    --os.execute('choice /n /d:y /t:' .. math.min(s, 9999) .. ' > NUL')

    -- *nix
    os.execute('sleep ' .. s)
end

local d
repeat
    d = target - os.time()
    if d <= 0 then break end
    sleep(d) -- sleep for the difference
until false

print'Target time has arrived.'


理想情况下,您可以通过使用操作系统的调度程序来完成类似的操作,例如 cron (在* nix上)或任务计划程序在Windows上,控制脚本执行的时间.但是,如果您打算通过Lua处理时间安排,请浏览此页面在Lua中编程中.


Ideally, you'd accomplish something like this by having your operating system's scheduler, such as cron on *nix or Task Scheduler on Windows, control the timing of the script's execution. However, if you plan to handle the timing through Lua, have a look through this page in Programming in Lua.

编辑:上次使用我们的sleep函数,我们可以轻松地为Lua中的完整任务计划程序创建基础,该任务计划程序只需几行代码即可处理多个事件.

Making use of our sleep function from last time, we can easily create the foundation for a complete task scheduler in Lua that can handle multiple events with only a few lines of code.

local alarm = {}
local function sort_alarm(a, b) return a.time > b.time end
local function schedule(when, what)
    if os.time() <= when then
        table.insert(alarm, {time = when, event = what})
        table.sort(alarm, sort_alarm)
    else -- What to do when a scheduled event is in the past?
        what()
    end
end
local function run_scheduler()
    local d
    while #alarm > 0 do
        d = alarm[#alarm].time - os.time()
        if d <= 0 then
            -- Pop the latest alarm from the stack and call it.
            table.remove(alarm).event()
        else
            sleep(d)
        end
    end
end

-- Schedule some events.
schedule(os.time{year = 2013, month = 11, day = 22, hour = 9}, function()
    print'This function runs at a specific point in time.'
end)

schedule(os.time() + 30, function()
    print'This function will run 30 seconds from the start of the script.'
end)

schedule(os.time() + 5, function()
    print'This function will run 5 seconds from the start of the script.'
    schedule(os.time() + 10, function()
        print'You can even schedule new functions this way.'
        print'This one will run 15 seconds from the start of the script.'
    end)
end)

local function repeater()
    print'How about a repeating event?'
    print'This function will run every 10 seconds.'
    schedule(os.time() + 10, repeater)
end
schedule(os.time() + 10, repeater)

-- Start the scheduler loop.
run_scheduler()

-- No more events left at this point, thus the script will end.


结束语,我必须注意,如果您打算认真使用此功能,则将来希望将sleep功能替换为更可靠的功能.用户Wiki上有一个页面,其中列出了一些解决方案.如果要碰巧使用LuaJIT,请使用 FFI ,这是从LuaJIT进行的最简单的操作


In closing, I must note that if you plan to use this seriously, you'll want to replace the sleep function with something more robust in the future. There's a page on the users wiki listing some solutions. I'd say it's easiest to do from LuaJIT using the FFI, if you happen to be using it already.

这篇关于如何在Lua中的特定日期和特定时间执行全局功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆