Quick tip. Is my process alive? (in Ruby)
How do you figure whether a process is currently running, in a reasonably portable manner? I keep forgetting how to do this for some reason, and needed it for my tinkering with Babushka so might as well write it down.
Let’s assume you’re writing a script that needs to run regularly, but may take a variable amount of time to run, and you really do not want it to run multiple times in parallel—for instance because that would exhaust your system’s resources.
This is a classic use case when using Cron, if the interval at which you run the script can be lower than the script duration.
A typical pattern is to make sure your script writes a “pidfile” containing your process identifier in a well-known location when starting:
Pathname.new('~/.shebam.pid').write(Process.pid)
How do you figure out whether a previous version is still running? Just read the
pidfile of course, which leaves you with a handy integer.
You could parse the output of ps(1)
, but that varies fairly wildly between Unix flavours.
You could look it up in /proc
, but that’s Linux-only.
It turns out that standard Unix can help us out. Killing a process with signal 0 (the “null” signal) will perform error-checking but not send a signal.
A method being worth a thousand words:
module Process
def exist?(pid)
Process.kill(0, pid)
true
rescue Errno::ESRCH
false
end
module_function :exist?
end
A bit of wrapping and you’re good to go. Here’s a working example. Still has a window of opportunity (between checking checking for the process and writing the PID file), but it’s now a pretty small one, and one that’s fixable using atomic file locking for instance.