最简单的方法让lua脚本等待/暂停/睡眠/阻止几秒钟?

Mat*_*tin 32 lua

我无法弄清楚如何让lua做任何常见的计时技巧,比如

  • sleep - 停止线程上的所有操作

  • 暂停/等待 - 不要继续执行下一个命令,但允许应用程序中的其他代码继续

  • block - 在当前命令返回之前不要继续执行下一个命令

我读过那个

while os.clock()<time_point do 
--nothing
end
Run Code Online (Sandbox Code Playgroud)

吃掉CPU时间.

有什么建议?我缺少一个API调用吗?

更新:我很久以前写过这个问题试图让WOW Lua按计划重播动作(即站立,等待1秒,跳舞,等待2秒,坐下.没有停顿,这些几乎都发生在同一季度. )事实证明,WOW故意禁用了几乎所有允许在时钟上执行操作的内容,因为它可能会破坏游戏或启用机器人.我想要在它被带走后重新创建一个时钟,我必须做一些疯狂的事情,比如创建一个工作数组(有一个动作和执行时间),然后在一堆常见事件上注册一个事件处理程序,比如鼠标移动,然后在偶数处理程序中,处理任何时间已到的动作.事件处理程序实际上不会每X毫秒发生一次,但如果它每隔2-100毫秒发生一次,它就足够接近了.可悲的是,我从未尝试过.

zsl*_*ton 20

[我打算将此作为评论约翰克罗马蒂的帖子,但没有意识到你不能在评论中使用格式.]

我同意.使用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;
}
Run Code Online (Sandbox Code Playgroud)

然后,在main中,执行:

lua_pushcfunction(L, lua_sleep);
lua_setglobal(L, "sleep");
Run Code Online (Sandbox Code Playgroud)

其中"L"是你的lua_State.然后,在从C/C++调用的Lua脚本中,您可以通过调用以下函数来使用您的函数:

sleep(1000) -- Sleeps for one second
Run Code Online (Sandbox Code Playgroud)


Mic*_*man 19

如果您碰巧在项目中使用了LuaSocket,或者只是安装了它并且不介意使用它,您可以使用socket.sleep(time)睡眠一段时间(以秒为单位)的功能.

这适用于Windows和Unix,您无需编译其他模块.

我应该补充说,该函数支持小数秒作为参数,socket.sleep(0.5)即将睡眠半秒.它Sleep()在Windows和nanosleep()其他地方使用,因此time在太低时可能会出现Windows准确性问题.


Kkn*_*knd 10

你不能在没有吃CPU的情况下在纯Lua中做到这一点,但是有一种简单,不可移植的方式:

os.execute("睡眠1")

(它会阻止)

显然,这仅适用于"sleep 1"是有效命令的操作系统,例如Unix,而不是Windows.


小智 8

对于Windows,你可以这样做:

os.execute("CHOICE /n /d:y /c:yn /t:5")
Run Code Online (Sandbox Code Playgroud)


Joe*_* DF 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
Run Code Online (Sandbox Code Playgroud)

暂停功能 - 用法:pause() -- pause and waits for the Return key

function pause()
   io.stdin:read'*l'
end
Run Code Online (Sandbox Code Playgroud)

希望,这就是你所需要的!:D - Joe DF


Flu*_*uff 6

没有比这更容易的了。睡眠可能在您的 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
Run Code Online (Sandbox Code Playgroud)

  • 当我寻找一个简单的解决方案时,我一直更讨厌 lua ... (3认同)