luajit ffi 应用之sleep实现

我们知道原生lua如果我们想使用sleep方法,只能借助于os这个模块,这种就不再多说。下面采用luajit的ffi模块去实现sleep。下面介绍两种方法,大题上都是一样的通过luajit的ffi模块去调用C的方法。

  • 借助C里的poll方法(如果你不熟悉poll方法,可以通过man 2 去查看帮助文档)

     local ffi=require('ffi')
     ffi.cdef[[
          void Sleep(int ms);
          int poll(struct pollfd *fds, unsigned long nfds, int timeout);
     ]]
    
     local sleep
     if ffi.os == "Windows" then
         function sleep(s)
             ffi.C.Sleep(s*1000)
         end
     else
         function sleep(s)
              ffi.C.poll(nil, 0, s*1000)
         end
     end
    
    for i=1, 2 do
         ngx.say(".")
         ngx.flush()
         sleep(1)
    end
    
  • 借助C的select方法(如果你不熟悉select方法,可以通过man 2 select去查看帮助文档),此方法可以精确到纳秒

    local ffi=require('ffi')
    ffi.cdef[[
        int select(int nfds, struct fd_set *readfds, struct fd_set *writefds, struct fd_set *exceptfds, const struct timespec *timeout);
        struct timespec { long    tv_sec;  long tv_nsec;  };
    ]]
    local time = ffi.new("struct timespec", {5, 200000})
    ffi.C.select(1,nil,nil,nil,time)
    ngx.say("sleep finish")
    

需要注意的是: ffi.cdef的时候如果定义struct,不要使用typedef的方式,如果使用这种方式,将不能使用ffi.new

参考:

OpenResty最佳实践FFI

ffi官方手册