How can I check from Ruby whether a process with a certain pid is running?

34,245

Solution 1

If it's a process you expect to "own" (e.g. you're using this to validate a pid for a process you control), you can just send sig 0 to it.

>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
    from (irb):5:in `kill'
    from (irb):5
>> 

Solution 2

The difference between the Process.getpgid and Process::kill approaches seems to be what happens when the pid exists but is owned by another user. Process.getpgid will return an answer, Process::kill will throw an exception (Errno::EPERM).

Based on that, I recommend Process.getpgid, if just for the reason that it saves you from having to catch two different exceptions.

Here's the code I use:

begin
  Process.getpgid( pid )
  true
rescue Errno::ESRCH
  false
end

Solution 3

@John T, @Dustin: Actually, guys, I perused the Process rdocs, and it looks like

Process.getpgid( pid )

is a less violent means of applying the same technique.

Solution 4

For child processes, other solutions like sending a signal won't behave as expected: they will indicate that the process is still running when it actually exited.

You can use Process.waitpid if you want to check on a process that you spawned yourself. The call won't block if you're using the Process::WNOHANG flag and nil is going to be returned as long as the child process didn't exit.

Example:

pid = Process.spawn('sleep 5')
Process.waitpid(pid, Process::WNOHANG) # => nil
sleep 5
Process.waitpid(pid, Process::WNOHANG) # => pid

If the pid doesn't belong to a child process, an exception will be thrown (Errno::ECHILD: No child processes).

The same applies to Process.waitpid2.

Solution 5

This is how I've been doing it:

def alive?(pid)
  !!Process.kill(0, pid) rescue false
end
Share:
34,245
Pistos
Author by

Pistos

Updated on January 13, 2020

Comments

  • Pistos
    Pistos over 4 years

    If there is more than one way, please list them. I only know of one, but I'm wondering if there is a cleaner, in-Ruby way.