【问题标题】:Lua: how to check whether a process is runningLua:如何检查进程是否正在运行
【发布时间】:2015-06-04 14:19:31
【问题描述】:

我想从 Lua 启动一个进程并监视该进程是否仍在运行。

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

【问题讨论】:

    标签: process lua


    【解决方案1】:

    其中一种直截了当的方法是使用 io.popen() 并监控其输出或使用其他一些 Linux 工具(如 ps)自行处理它们。

    另一种方法是使用一些 Lua POSIX 绑定,例如 POSIX.signalPOSIX.unistd#fork()

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • uf,你应该提到你需要它专门用于 Windows :)
      【解决方案3】:

      如果您使用的是 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 的情况下,您仍然可以返回结果以查看孩子是否已退出,然后继续执行其他操作。

      【讨论】:

        【解决方案4】:

        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"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-05-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-03
          • 2017-06-10
          相关资源
          最近更新 更多