6

I would like to start a process from Lua and monitor whether the process is still running.

[EDIT] I know starting can be achieved by os:execute, but this is blocking. I would like to find a way to start a process non-blocking and monitor whether it still runs.

Ben
  • 1,519
  • 23
  • 39

4 Answers4

0

One of the blunt ways would be just using io.popen() and monitoring it's output or processes them self using some other Linux tool like ps.

Another way would be using some Lua POSIX bindings like POSIX.signal and POSIX.unistd#fork()

Kamiccolo
  • 7,758
  • 3
  • 34
  • 47
0

The following Lua library provides functions to (asynchronously) start and monitor processes.

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

Ben
  • 1,519
  • 23
  • 39
0

If you're using luajit you can use the foreign function interface to directly call the OS api functions. e.g. for Linux or similar.

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

You'll see that with the WNOHANG = 1 you can still get a result back to see if the child has exited but then carry on to do other things.

hookenz
  • 36,432
  • 45
  • 177
  • 286
-3

Coroutines in Lua allow you to do what you need (since 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"