我不知道如何让lua做任何常见的计时技巧,例如
我读过
while os.clock()<time_point do
--nothing
end耗尽CPU时间。
有什么建议吗?我遗漏了一个API调用吗?
UPDATE:我很久以前就写过这个问题,试图让哇哇Lua按计划重放动作(即站立、等待1秒、跳舞、等待2秒、坐下)。如果没有暂停,这些事件几乎都会在同一秒钟内发生。) 原来,WOW故意使所有允许在时钟上操作的东西都被禁用了,因为它可以破坏游戏或启用机器人。我想,一旦时钟被拿走,我就必须做一些疯狂的事情,比如创建一个工作数组(包括一个动作和执行时间),然后在一堆常见事件上注册一个事件处理程序,比如鼠标移动,然后在偶数处理程序中处理任何时间已经到来的操作。事件处理程序实际上不会每隔X毫秒发生一次,但是如果它每2-100毫秒发生一次,那么它就足够接近了。可惜我没试过。
发布于 2014-06-04 12:26:11
没有比这更容易的了。睡眠可能在您的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发布于 2009-07-07 15:25:59
[我本打算在约翰·克罗马蒂上发表这篇评论,但没想到你不能在评论中使用格式化。]
我同意。使用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;
}然后,主要地,做:
lua_pushcfunction(L, lua_sleep);
lua_setglobal(L, "sleep");"L“是你的lua_State。然后,在从C/C++调用的Lua脚本中,您可以通过以下方式使用您的函数:
sleep(1000) -- Sleeps for one second发布于 2011-10-31 08:32:16
如果您碰巧在您的项目中使用了LuaSocket,或者只是安装了它,并且不介意使用它,您可以使用socket.sleep(time)函数,它可以在给定的时间内(以秒为单位)休眠。
这既适用于Windows,也适用于Unix,您不必编译其他模块。
我应该补充的是,函数支持小数秒作为参数,即socket.sleep(0.5)将睡眠半秒。它在Windows上使用Sleep(),在其他地方使用nanosleep(),因此当time太低时,您可能会对Windows的准确性产生问题。
https://stackoverflow.com/questions/1034334
复制相似问题