best way to check if pid is dead?

bukzor workitharder at gmail.com
Wed May 21 18:36:55 EDT 2008


On May 21, 1:27 pm, bukzor <workithar... at gmail.com> wrote:
> On May 21, 12:13 pm, Roy Smith <r... at panix.com> wrote:
>
>
>
> > In article
> > <90ecca29-c4d8-4e89-908a-93850d7de... at i76g2000hsf.googlegroups.com>,
>
> >  bukzor <workithar... at gmail.com> wrote:
> > > 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/009695399/functions/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)



More information about the Python-list mailing list