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