我正在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
答案 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做起来最简单。