On May 21, 1:27*pm, bukzor <workithar...@gmail.comwrote:
On May 21, 12:13 pm, Roy Smith <r...@panix.comwrote:
In article
<90ecca29-c4d8-4e89-908a-93850d7de...@i76g2000hsf.googlegroups.com>,
*bukzor <workithar...@gmail.comwrote:
Does anyone have a pythonic way to check if a process is dead, given
the pid?
This is the function I'm using is quite OS dependent. A good candidate
might be "try: kill(pid)", since it throws an exception if the pid is
dead, but that sends a signal which might interfere with the process.
Thanks.
--Buck
The canonical way is to do kill(pid, 0). *If it doesn't throw, the process
exists. *No actual signal is sent to the process either way.
Of course, the process could exit immediately after the kill() call, so by
the time you find out it's alive, it's dead. *Such is life.
Thanks! That's exactly what I was looking for. A little more
background:
"If sig is 0 (the null signal), error checking is performed but no
signal is actually sent. The null signal can be used to check the
validity of pid."
Taken from :http://www.opengroup.org/onlinepubs/...ions/kill.html
Here are the functions I wrote with this information. There are three
functions:
kill() is similar to os.kill, but returns True if the pid is dead and
throws less exceptions
dead() checks if a process is dead, and gets rid of zombies if
necessary
goodkill() kills a pid by sending gradually harser signals until dead.
def kill(pid, signal=0):
"""sends a signal to a process
returns True if the pid is dead
with no signal argument, sends no signal"""
#if 'ps --no-headers' returns no lines, the pid is dead
from os import kill
try: return kill(pid, signal)
except OSError, e:
#process is dead
if e.errno == 3: return True
#no permissions
elif e.errno == 1: return False
else: raise
def dead(pid):
if kill(pid): return True
#maybe the pid is a zombie that needs us to wait4 it
from os import waitpid, WNOHANG
try: dead = waitpid(pid, WNOHANG)[0]
except OSError, e:
#pid is not a child
if e.errno == 10: return False
else: raise
return dead
#def kill(pid, sig=0): pass #DEBUG: test hang condition
def goodkill(pid, interval=1, hung=20):
"let process die gracefully, gradually send harsher signals if
necessary"
from signal import SIGTERM, SIGINT, SIGHUP, SIGKILL
from time import sleep
for signal in [SIGTERM, SIGINT, SIGHUP]:
if kill(pid, signal): return
if dead(pid): return
sleep(interval)
i = 0
while True:
#infinite-loop protection
if i < hung: i += 1
else:
print "Process %s is hung. Giving up kill." % pid
return
if kill(pid, SIGKILL): return
if dead(pid): return
sleep(interval)