我无法弄清楚如何让lua做任何常见的计时技巧,例如
睡眠 - 停止线程上的所有操作
暂停/等待 - 不要继续下一步 命令,但允许其他代码 申请继续
阻止 - 不要再继续下一个命令 当前的一个返回
我读过那个
while os.clock()<time_point do
--nothing
end
耗尽CPU时间。
有什么建议吗?我缺少一个API调用吗?
更新:很久以前我写了这个问题试图让WOW Lua按计划重播动作(即站立,等待1秒,跳舞,等待2秒,坐下。没有停顿,几乎所有这些都发生在同一季度的第二季。)As it turned out WOW had purposely disabled pretty much everything that allows doing action on a clock because it could break the game or enable bots.我想要在它被带走后重新创建一个时钟,我必须做一些疯狂的事情,比如创建一个工作数组(带有动作和执行)然后在一堆常见事件上注册一个事件处理程序,比如鼠标移动,然后在偶数处理程序中,处理任何时间已到的动作。事件处理程序实际上不会每X毫秒发生一次,但如果它每隔2-100毫秒发生一次,它就足够接近了。可悲的是,我从未尝试过。
答案 0 :(得分:20)
[我打算在John Cromartie's帖子上发表此评论,但没有意识到您无法在评论中使用格式。]
我同意。使用os.execute()将它删除到shell肯定会起作用,但通常使shell调用很昂贵。在运行时包装一些C代码会更快。在Linux系统上的C / C ++中,您可以使用:
static int lua_sleep(lua_State *L)
{
int m = static_cast<int> (luaL_checknumber(L,1));
usleep(m * 1000);
// usleep takes microseconds. This converts the parameter to milliseconds.
// Change this as necessary.
// Alternatively, use 'sleep()' to treat the parameter as whole seconds.
return 0;
}
然后,在main中,执行:
lua_pushcfunction(L, lua_sleep);
lua_setglobal(L, "sleep");
其中“L”是你的lua_State。然后,在从C / C ++调用的Lua脚本中,您可以通过调用:
来使用您的函数sleep(1000) -- Sleeps for one second
答案 1 :(得分:18)
如果您碰巧在项目中使用了LuaSocket,或者只是安装了它并且不介意使用它,您可以使用socket.sleep(time)
函数在预定的时间内休眠(在几秒钟内。
这适用于Windows和Unix,您无需编译其他模块。
我应该补充一点,该函数支持小数秒作为参数,即socket.sleep(0.5)
将睡半秒。它在Windows上使用Sleep()
,在其他地方使用nanosleep()
,因此当time
过低时,您可能会遇到Windows准确性问题。
答案 2 :(得分:10)
你不能在没有吃CPU的情况下在纯Lua中做到这一点,但是有一种简单的,不可移植的方式:
os.execute(“sleep 1”)
(它会阻止)
显然,这仅适用于“sleep 1”是有效命令的操作系统,例如Unix,而不是Windows。
答案 3 :(得分:8)
os.execute("CHOICE /n /d:y /c:yn /t:5")
答案 4 :(得分:7)
睡眠功能 - 用法:sleep(1) -- sleeps for 1 second
local clock = os.clock
function sleep(n) -- seconds
local t0 = clock()
while clock() - t0 <= n do
end
end
暂停功能 - 用法:pause() -- pause and waits for the Return key
function pause()
io.stdin:read'*l'
end
希望,这就是你所需要的! :D - Joe DF
答案 5 :(得分:4)
它并不比这更容易。睡眠可能在你的FLTK或其他任何东西中实现,但这涵盖了在没有特殊事件中断的情况下进行标准排序系统睡眠的所有最佳方法。看哪:
-- we "pcall" (try/catch) the "ex", which had better include os.sleep
-- it may be a part of the standard library in future Lua versions (past 5.2)
local ok,ex = pcall(require,"ex")
if ok then
-- print("Ex")
-- we need a hack now too? ex.install(), you say? okay
pcall(ex.install)
-- let's try something else. why not?
if ex.sleep and not os.sleep then os.sleep = ex.sleep end
end
if not os.sleep then
-- we make os.sleep
-- first by trying ffi, which is part of LuaJIT, which lets us write C code
local ok,ffi = pcall(require,"ffi")
if ok then
-- print("FFI")
-- we can use FFI
-- let's just check one more time to make sure we still don't have os.sleep
if not os.sleep then
-- okay, here is our custom C sleep code:
ffi.cdef[[
void Sleep(int ms);
int poll(struct pollfd *fds,unsigned long nfds,int timeout);
]]
if ffi.os == "Windows" then
os.sleep = function(sec)
ffi.C.Sleep(sec*1000)
end
else
os.sleep = function(sec)
ffi.C.poll(nil,0,sec*1000)
end
end
end
else
-- if we can't use FFI, we try LuaSocket, which is just called "socket"
-- I'm 99.99999999% sure of that
local ok,socket = pcall(require,"socket")
-- ...but I'm not 100% sure of that
if not ok then local ok,socket = pcall(require,"luasocket") end
-- so if we're really using socket...
if ok then
-- print("Socket")
-- we might as well confirm there still is no os.sleep
if not os.sleep then
-- our custom socket.select to os.sleep code:
os.sleep = function(sec)
socket.select(nil,nil,sec)
end
end
else
-- now we're going to test "alien"
local ok,alien = pcall(require,"alien")
if ok then
-- print("Alien")
-- beam me up...
if not os.sleep then
-- if we still don't have os.sleep, that is
-- now, I don't know what the hell the following code does
if alien.platform == "windows" then
kernel32 = alien.load("kernel32.dll")
local slep = kernel32.Sleep
slep:types{ret="void",abi="stdcall","uint"}
os.sleep = function(sec)
slep(sec*1000)
end
else
local pol = alien.default.poll
pol:types('struct', 'unsigned long', 'int')
os.sleep = function(sec)
pol(nil,0,sec*1000)
end
end
end
elseif package.config:match("^\\") then
-- print("busywait")
-- if the computer is politically opposed to NIXon, we do the busywait
-- and shake it all about
os.sleep = function(sec)
local timr = os.time()
repeat until os.time() > timr + sec
end
else
-- print("NIX")
-- or we get NIXed
os.sleep = function(sec)
os.execute("sleep " .. sec)
end
end
end
end
end
答案 6 :(得分:3)
我将实现一个简单的函数来将主机系统的睡眠函数包装在C中。
答案 7 :(得分:3)
require 'alien'
if alien.platform == "windows" then
kernel32 = alien.load("kernel32.dll")
sleep = kernel32.Sleep
sleep:types{ret="void",abi="stdcall","uint"}
else
-- untested !!!
libc = alien.default
local usleep = libc.usleep
usleep:types('int', 'uint')
sleep = function(ms)
while ms > 1000 do
usleep(1000)
ms = ms - 1000
end
usleep(1000 * ms)
end
end
print('hello')
sleep(500) -- sleep 500 ms
print('world')
答案 8 :(得分:3)
对于第二个请求,暂停/等待,在Lua中停止处理并继续运行您的应用程序,您需要协同程序。你最终得到了如下的一些C代码:
Lthread=lua_newthread(L);
luaL_loadfile(Lthread, file);
while ((status=lua_resume(Lthread, 0) == LUA_YIELD) {
/* do some C code here */
}
在Lua中,您有以下内容:
function try_pause (func, param)
local rc=func(param)
while rc == false do
coroutine.yield()
rc=func(param)
end
end
function is_data_ready (data)
local rc=true
-- check if data is ready, update rc to false if not ready
return rc
end
try_pause(is_data_ready, data)
答案 9 :(得分:3)
Pure Lua仅使用ANSI标准C中的内容.Luiz Figuereido的lposix module包含了做更多系统事物所需的大部分内容。
答案 10 :(得分:2)
我赞同John关于睡眠功能的包装。 你也可以使用这个包装的睡眠函数在lua中实现一个暂停函数(它会简单地睡眠,然后检查某个条件是否经常发生变化)。另一种方法是使用钩子。
我不完全确定你的第三个要点是什么意思(在执行下一个命令之前通常不会完成命令吗?)但钩子也可以帮助解决这个问题。
请参阅: Question: How can I end a Lua thread cleanly? 有关使用挂钩的示例。
答案 11 :(得分:2)
您可以使用:
os.execute("sleep 1") -- I think you can do every command of CMD using os.execute("command")
或者您可以使用:
function wait(waitTime)
timer = os.time()
repeat until os.time() > timer + waitTime
end
wait(YourNumberHere)
答案 12 :(得分:1)
使用Alien作为libc / msvcrt包装器也很容易:
> luarocks install alien
然后来自lua:
require 'alien'
if alien.platform == "windows" then
-- untested!!
libc = alien.load("msvcrt.dll")
else
libc = alien.default
end
usleep = libc.usleep
usleep:types('int', 'uint')
function sleep(ms)
while ms > 1000 do
usleep(1000)
ms = ms - 1000
end
usleep(1000 * ms)
end
print('hello')
sleep(500) -- sleep 500 ms
print('world')
警告lector:我没有在MSWindows上尝试过这个;我甚至都不知道msvcrt是否有usleep()
答案 13 :(得分:1)
我从Lua开始,然后我发现我想要查看结果,而不仅仅是好的旧命令行flash。所以我只是将以下行添加到我的文件中,然后是标准:
please press any key to continue...
os.execute("PAUSE")
我的示例文件只是一个打印,然后是暂停声明,因此我确信您不需要在此处发布。
我不确定正在运行完整脚本的进程的CPU含义。但是,在调试中停止代码中间流程可能很有用。
答案 14 :(得分:1)
我相信你可以使用Windows os.execute("ping 1.1.1.1 /n 1 /w <time in milliseconds> >nul
作为一个简单的计时器。
(以毫秒为单位插入时间时删除“&lt;&gt;”)(其余代码与>nul
之间有空格)
答案 15 :(得分:1)
你想要win.Sleep(milliseconds)
,意思是。
是的,你绝对不想像你描述的那样忙碌等待。
答案 16 :(得分:0)
这应该有效:
os.execute("PAUSE")
答案 17 :(得分:0)
cy = function()
local T = os.time()
coroutine.yield(coroutine.resume(coroutine.create(function()
end)))
return os.time()-T
end
sleep = function(time)
if not time or time == 0 then
time = cy()
end
local t = 0
repeat
local T = os.time()
coroutine.yield(coroutine.resume(coroutine.create(function() end)))
t = t + (os.time()-T)
until t >= time
end
答案 18 :(得分:0)
您可以这样做:
function Sleep(seconds)
local endTime = os.time() + seconds
while os.time() < endTime do
end
end
print("This is printed first!")
Sleep(5)
print("This is printed 5 seconds later!")