如何在Lua的特定时间执行特定日的全局功能?

时间:2013-11-20 23:09:56

标签: lua autoplay

我正在Lua编写一个脚本,其中许多其他函数会在特定日期的特定时间执行单个循环。按下按钮时启动循环,思考一下这一段时间我现在已经收集到了我必须使用os.time检查系统时间,以表格形式返回日期,这非常有用。我唯一坚持的是如何表达它,以及是否可以包含os.time的多个定义;所以在第(x)天,loop1将运行,并且在第(y)个循环2将发生,依此类推。我很可能过于复杂化了......

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

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

1 个答案:

答案 0 :(得分:1)

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

即便如此,如果你正确地与os.time()进行比较,进入一个无限循环来检查时间是否会最大限度地延长Lua VM的CPU使用率,因为无限循环是不会做的。这将可能冻结过程,这可能就是“崩溃和焚烧”的意思。

最后但同样重要的是,将当前时间与未来时间与==进行比较通常是一个坏主意,因为条件在确切的期望时间内准确执行的概率很低。

我会尽可能长时间地推荐sleeping,直到最早的任务准备就绪。这样,您可以避免在持续轮询时占用任何不必要的CPU时间。从Lua,你可以做这样的事情。

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.'

理想情况下,通过让操作系统的调度程序(如Windows上的cron或Windows上的Task Scheduler)控制脚本执行的时间,您可以完成类似的操作。但是,如果您计划通过Lua处理时间,请查看 Lua中的编程中的this page


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

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功能替换为将来更强大的功能。用户维基上有一个page列出了一些解决方案。如果您恰好使用FFI,我会说使用{{3}}从LuaJIT做起来最简单。