Sleep 函數

lua-users home
Wiki

常見需要暫停(sleep)程式一段時間,最好不用忙碌等待。

並未在 ANSI C 中找不到這個不需忙碌等待來完成此功能的函數,因此標準 Lua 中也找不到。不過,有擴充函式庫和呼叫外部程式可以完成這件事。

解決方案:忙碌等待

local clock = os.clock
function sleep(n)  -- seconds
  local t0 = clock()
  while clock() - t0 <= n do end
end
-- warning: clock can eventually wrap around for sufficiently large n
-- (whose value is platform dependent).  Even for n == 1, clock() - t0
-- might become negative on the second that clock wraps.

解決方案:C 擴充

ExtensionProposal 中有一個 sleep 函數。這個函數可能會呼叫 Win32 Sleep 或 POSIX usleep。以下是 [usleep/sleep C 封裝函式] 的範例。

LuaApr[1] binding 擁有可在 Windows 和 UNIX 上執行且支援次秒解析度的 LuaApr 函數。

lalarm 函式庫[1] 可以設定 POSIX 的警報。

winapi(僅限於 Windows)有一個 [sleep] 函數。 [github]

如果提供 FFI 介面(Alien 或 c/invoke -- BindingCodeToLua),你可以呼叫擁有的任何 OS 函數。

解決方案:sleep 命令

function sleep(n)
  os.execute("sleep " .. tonumber(n))
end

Windows 沒有內建此命令。不過,Windows Server Resource Kit 中有 sleep。Cygwin 和 MinGW 中也有 sleep。另外,Windows 7 中也有「timeout」可用。

  os.execute("timeout " .. tonumber(n)) -- specific to win7 (and probably higher) 

解決方案:ping 或其他程式

function sleep(n)
  if n > 0 then os.execute("ping -n " .. tonumber(n+1) .. " localhost > NUL") end
end
-- version 20100715 - fixed off-by-one second

這個方法主要用於沒有 sleep 命令的 Windows。還有其他變形,例如 "perl -e 'sleep(" .. tonumber(n) .. ")'""php -r sleep(" .. tonumber(n) .. ");"

解決方案:I/O 等待

io.stdin:read'*l'

這個方法並非 sleep,但是在類似狀況下會很有用。這個方法會等待使用者按下 Enter 鍵。

解決方案:使用 WScript(Windows)

function sleep(n)
  local vb = "test.vbs"
  local f = assert(io.open(vb,"w"))
  f:write("WScript.Sleep(" .. (tonumber(n) * 1000) .. ")\n")
  f:close()
  os.execute(vb)
end

請參閱 [2]

解決方案:sleep()

POSIX sleep() 呼叫提供整數秒的 sleep。

require "posix"

posix.sleep(3)

解決方案:socket.sleep()

LuaSocket? 模組提供一個 sleep 函數。

socket = require("socket")

function sleep(sec)
    socket.sleep(sec)
end

sleep(0.2)

解決方案:ngx.sleep()

Nginx Lua 模組提供一個 sleep 函數。可以指定時間解析度最高到 0.001 秒(也就是 1 毫秒)。在幕後,這個方法使用 Nginx 計時器。

ngx.sleep(sec)

解決方案:lsocket.select()

如果可以忍受 socket 函式庫相依性,select() 超時會提供一個相當具有可攜性的次秒 sleep。

local lsocket  = require("lsocket")

function sleep(sec)
    lsocket.select(sec)
end

sleep(2)

解決方案:LuaJIT FFI/LuaFFI

local ffi = require "ffi"
ffi.cdef "unsigned int sleep(unsigned int seconds);"
ffi.C.sleep(2)

解決方案:os.time()

function sleep(s)
  local ntime = os.time() + s
  repeat until os.time() > ntime
end

解決方案:os.clock()

. .

使用 os.clock() 方法代替 os.time(),可以將精度降到十分之一秒,而 os.time() 僅允許基於時間戳記的間隔,執行時可以介於 0.1 到 1 秒之間。os.time() 方法非常適合超過 2 秒以上的較長時間,那時精度並非那麼重要。

function sleep(s)
  local ntime = os.clock() + s/10
  repeat until os.clock() > ntime
end

另請參閱


最近更新 · 偏好設定
編輯 · 歷史
最後編輯於 2019 年 10 月 20 日 下午 2:12 GMT (差異)