Lua:如何检查进程是否为运行
Lua: how to check whether a process is running
我想从Lua开始一个进程,监视进程是否还在运行。
[编辑]
我知道启动可以通过 os:execute 实现,但这是阻塞的。我想找到一种非阻塞启动进程并监视它是否仍在运行的方法。
一种直截了当的方法就是使用 io.popen() and monitoring it's output or processes them self using some other Linux tool like ps.
另一种方法是使用一些 Lua POSIX 绑定,例如 POSIX.signal and POSIX.unistd#fork()
以下 Lua 库提供了(异步)启动和监视进程的功能。
Lua 中的协程允许您做您需要的事情(自 Lua 5.0 起):
local function Body()
print( "First resume" )
coroutine.yield()
print( "Second resume" )
coroutine.yield()
print( "Final resume" )
end
local co = coroutine.create( Body )
print( type( co ) ) -- prints "thread"
coroutine.resume( co ) -- prints "First resume"
print( "After first yield" )
coroutine.resume( co ) -- prints "Second resume"
print( "After second yield" )
coroutine.resume( co ) -- prints "Final resume"
print( coroutine.status( co ) ) -- "suspended", "dead"
如果您使用luajit,您可以使用外部函数接口直接调用OS api 函数。例如对于 Linux 或类似的。
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
int fork(void);
int execlp(const char* file, const char *arg, ...);
int waitpid(int pid, int *status, int options);
void _exit(int status);
unsigned int sleep(unsigned int seconds);
]]
local pid = C.fork()
if pid > 0 then -- parent
print("Waiting for child process:");
local status = ffi.new('int[1]')
local WNOHANG = 1
local done = false
while not done do
local id = C.waitpid(-1, status, WNOHANG)
if id == pid then
done = true
elseif pid < 0 then
print("error occurred")
os.exit(-1)
else
print("status=",status[0])
C.sleep(1)
-- do other stuff. We aren't waiting
end
end
print("Child exited with status=", status[0])
elseif pid == 0 then -- child
print("Starting child")
C.execlp('sleep', 'sleep', '5')
C._exit(-1) -- exec never returns
elseif pid < 0 then -- failure
print("failed to fork")
end
你会看到,使用 WNOHANG = 1 你仍然可以得到一个结果,看看 child 是否已经退出,然后继续做其他事情。
我想从Lua开始一个进程,监视进程是否还在运行。
[编辑] 我知道启动可以通过 os:execute 实现,但这是阻塞的。我想找到一种非阻塞启动进程并监视它是否仍在运行的方法。
一种直截了当的方法就是使用 io.popen() and monitoring it's output or processes them self using some other Linux tool like ps.
另一种方法是使用一些 Lua POSIX 绑定,例如 POSIX.signal and POSIX.unistd#fork()
以下 Lua 库提供了(异步)启动和监视进程的功能。
Lua 中的协程允许您做您需要的事情(自 Lua 5.0 起):
local function Body()
print( "First resume" )
coroutine.yield()
print( "Second resume" )
coroutine.yield()
print( "Final resume" )
end
local co = coroutine.create( Body )
print( type( co ) ) -- prints "thread"
coroutine.resume( co ) -- prints "First resume"
print( "After first yield" )
coroutine.resume( co ) -- prints "Second resume"
print( "After second yield" )
coroutine.resume( co ) -- prints "Final resume"
print( coroutine.status( co ) ) -- "suspended", "dead"
如果您使用luajit,您可以使用外部函数接口直接调用OS api 函数。例如对于 Linux 或类似的。
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
int fork(void);
int execlp(const char* file, const char *arg, ...);
int waitpid(int pid, int *status, int options);
void _exit(int status);
unsigned int sleep(unsigned int seconds);
]]
local pid = C.fork()
if pid > 0 then -- parent
print("Waiting for child process:");
local status = ffi.new('int[1]')
local WNOHANG = 1
local done = false
while not done do
local id = C.waitpid(-1, status, WNOHANG)
if id == pid then
done = true
elseif pid < 0 then
print("error occurred")
os.exit(-1)
else
print("status=",status[0])
C.sleep(1)
-- do other stuff. We aren't waiting
end
end
print("Child exited with status=", status[0])
elseif pid == 0 then -- child
print("Starting child")
C.execlp('sleep', 'sleep', '5')
C._exit(-1) -- exec never returns
elseif pid < 0 then -- failure
print("failed to fork")
end
你会看到,使用 WNOHANG = 1 你仍然可以得到一个结果,看看 child 是否已经退出,然后继续做其他事情。