Can Python kill a child process that keeps on running?

Serge Orlov Serge.Orlov at gmail.com
Mon May 1 22:57:58 EDT 2006


I. Myself wrote:
> Serge Orlov wrote:
> > I. Myself wrote:
> >
> >> Suppose we spawn a child process with Popen.  I'm thinking of an
> >> executable file, like a compiled C program.
> >> Suppose it is supposed to run for one minute, but it just keeps going
> >> and going.  Does Python have any way to kill it?
> >>
> >> This is not hypothetical; I'm doing it now, and it's working pretty
> >> well, but I would like to be able to handle this run-on condition.  I'm
> >> using Windows 2000, but I want my program to be portable to linux.
> >>
> >
> > On linux it's pretty easy to do, just setup alarm signal. On windows
> > it's not so trivial to the point you cannot do it using python.org
> > distribution, you will need to poke in low level C API using win32
> > extensions or ctypes. AFAIK twisted package <http://twistedmatrix.com>
> > has some code to help you. Also take a look at buildbot sources
> > <http://buildbot.sf.net> that uses twisted. Buildbot has the same
> > problem as you have, it needs to kill run away or non-responding
> > processes.
> >
> That is bad news.   Thanks anyway; bad news is better than no news.

The good news is that I think you can work around it using only stock
2.4 modules. The idea is that you launch a separate watchdog process
and communicate with it using portable asynchronous channel (file
system or socket). Here is totally untested (not even passed the
compilation) code just to show the idea how to communicate
asynchronously over filesystem:
======= watchdog.py =========
import os, sys

timeout = int(sys.argv[1])
commdir = sys.argv[2]
worker_pid = int(sys.argv[3])
heart_beat = os.path.join(commdir, "heartbeat")
work_is_done = os.path.join(commdir, "done")

while True:
    if os.path.exists(work_is_done):
        break
    if os.path.exists(heartbeat):
        os.kill(worker_pid)
        break
    file(heart_beat, "w").close()
    time.sleep(timeout)
===========================

======= work_consumer.py ========

# launch worker process
# launch watchdog

def heart_beat():
    try:
        os.remove(heart_beat)
    except OSError:
        pass

def done():
    file(heart_beat, "w").close()


try:
    while True:
        data = worker.read()
        heart_beat()
        # process data
        if done:
            break
finally:
    done()
=============================

If you don't like so much file system activity, you can implement
asynchronous communications over local socket. It is also portable.




More information about the Python-list mailing list