开发者

In Ruby telling if a system process is still alive?

If I start an app in the following way

cmd = "some_app &"
`#{cmd}`

How can I find out if开发者_高级运维 the process is still alive? I know there are various ways of getting the pid of the running app, and I could then check if that was still available via ps -ef. However that would only tell me if there was an process that existed with the same pid, when the app could have been killed along time previously. The same issue exists with ps -ef | grep some_app approach.

Anybody any ideas of a clean way to achieve this?


This cannot be done in the general case; Unix's facilities for manipulating processes are limited and not well integrated with the rest of the kernel API (there is, for instance, no way to get a file descriptor for a process, that could be passed to select or similar).

You can use the wait family of functions to block or poll for a child process having exited. You can install a handler for SIGCHLD and be notified asynchronously when a child exits. And, with cooperation from the child process, you can use a pipe or socket to get more detail on what's going on. However, with active lack of cooperation from the child, you're hosed (for instance, a child that itself forks, exits in the child, and calls setsid in the grandchild has escaped wait tracking in the original parent).

Those are pretty much your options, unless you are prepared to go deep into the land of system specific code (for instance, some people have done clever things with ptrace, which is normally for debuggers, to solve the sorts of problem you're looking at -- but I would not try it except as a last resort).


Researched this on a prior project...

Apparently the common practice is use Process.kill(0, pid) to probe a pid to see whether a signal can be sent. This method will return true only if the process both exists and the caller has permission to signal it. A return value of false can mean that process doesn't exist or the user doesn't have appropriate permission or the pid is the wrong type (i.e a string) or ...

You can catch the particular exception that indicates non-existence, Errno::ESRCH, "No such process", distinguishing that from lack of permission etc.

def process_exists?(pid) begin Process.kill(0, pid) rescue Errno::ESRCH # "No such process" return false rescue Errno::EPERM # "Operation not permitted" # at least the process exists return true else return true end end

Obviously not bulletproof but it's a start...



$alive = true
Thread.new do
    `some_app`
    $alive = false
end

if $alive
  ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜