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
...
精彩评论