首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >让lua脚本等待/暂停/睡眠/阻塞几秒钟的最简单方法?

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

Stack Overflow用户
提问于 2009-06-23 18:35:30
回答 20查看 116.4K关注 0票数 36

我不知道如何让lua做任何常见的计时技巧,例如

  • 睡眠-停止线程上的所有操作
  • 暂停/等待--不要继续执行下一个命令,而是允许应用程序中的其他代码继续运行
  • 块-在当前命令返回之前不要继续执行下一个命令。

我读过

代码语言:javascript
复制
while os.clock()<time_point do 
--nothing
end

耗尽CPU时间。

有什么建议吗?我遗漏了一个API调用吗?

UPDATE:我很久以前就写过这个问题,试图让哇哇Lua按计划重放动作(即站立、等待1秒、跳舞、等待2秒、坐下)。如果没有暂停,这些事件几乎都会在同一秒钟内发生。) 原来,WOW故意使所有允许在时钟上操作的东西都被禁用了,因为它可以破坏游戏或启用机器人。我想,一旦时钟被拿走,我就必须做一些疯狂的事情,比如创建一个工作数组(包括一个动作和执行时间),然后在一堆常见事件上注册一个事件处理程序,比如鼠标移动,然后在偶数处理程序中处理任何时间已经到来的操作。事件处理程序实际上不会每隔X毫秒发生一次,但是如果它每2-100毫秒发生一次,那么它就足够接近了。可惜我没试过。

EN

回答 20

Stack Overflow用户

回答已采纳

发布于 2014-06-04 12:26:11

没有比这更容易的了。睡眠可能在您的FLTK或其他什么实现,但这涵盖了所有最好的方式来做标准类型的系统睡眠,没有特殊的事件中断。看:

代码语言:javascript
复制
-- 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
EN

Stack Overflow用户

发布于 2009-07-07 15:25:59

[我本打算在约翰·克罗马蒂上发表这篇评论,但没想到你不能在评论中使用格式化。]

我同意。使用os.execute()将其放到shell中肯定会有效,但一般来说,进行shell调用是很昂贵的。在运行时包装一些C代码要快得多。在Linux系统上的C/C++中,您可以使用:

代码语言:javascript
复制
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;
}

然后,主要地,做:

代码语言:javascript
复制
lua_pushcfunction(L, lua_sleep);
lua_setglobal(L, "sleep");

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

代码语言:javascript
复制
sleep(1000) -- Sleeps for one second
票数 22
EN

Stack Overflow用户

发布于 2011-10-31 08:32:16

如果您碰巧在您的项目中使用了LuaSocket,或者只是安装了它,并且不介意使用它,您可以使用socket.sleep(time)函数,它可以在给定的时间内(以秒为单位)休眠。

这既适用于Windows,也适用于Unix,您不必编译其他模块。

我应该补充的是,函数支持小数秒作为参数,即socket.sleep(0.5)将睡眠半秒。它在Windows上使用Sleep(),在其他地方使用nanosleep(),因此当time太低时,您可能会对Windows的准确性产生问题。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1034334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档