Lua:如何检查进程是否正在运行

我想从 Lua 开始一个进程,并监控这个进程是否仍在运行。

[编辑] 我知道可以通过 os:execute 来启动该进程,但这是阻塞的。我想找到一种非阻塞的方式来启动进程并监控它是否仍在运行。

点赞
用户1150918
用户1150918

一种简单粗暴的方式是直接使用[io.popen()](http://www.lua.org/manual/5.1/manual.html#pdf-io.popen)并监控它的输出,或者使用类似[ps](http://linuxcommand.org/man_pages/ps1.html)这样的其他Linux工具处理进程。

另一种方式是使用一些Lua POSIX绑定,例如[POSIX.signal](https://luaposix.github.io/luaposix/modules/posix.signal.html)[POSIX.unistd#fork()](https://luaposix.github.io/luaposix/modules/posix.unistd.html)

2015-06-04 17:34:24
用户2554220
用户2554220

以下 Lua 库提供了启动和监视进程的函数(异步)。

http://stevedonovan.github.io/winapi/

2015-06-05 08:45:08
用户2704138
用户2704138

Lua中的协程允许您执行所需操作(自Lua 5.0以来):

local function Body()
    print("第一次恢复")

    coroutine.yield()

    print("第二次恢复")

    coroutine.yield()

    print("最终恢复")
end

local co = coroutine.create(Body)

print(type(co)) -- 输出 "thread"

coroutine.resume(co) -- 输出 "第一次恢复"

print("第一个yield后")

coroutine.resume(co) -- 输出 "第二次恢复"

print("第二个yield后")

coroutine.resume(co) -- 输出 "最终恢复"

print(coroutine.status(co)) -- 输出 "suspended", "dead"
2015-06-05 16:49:06
用户134702
用户134702

如果你使用的是 luajit,那么你可以使用外部函数接口直接调用操作系统 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 时,你仍然可以获得结果来判断子进程是否已经退出然后继续做其他事情。

2016-07-08 02:02:12