Embedded python: how to force a break to endless looping Python script? (2)

David Bolen db3l at fitlinxx.com
Tue Aug 22 18:41:43 EDT 2000


"Warren Postma" <embed at NOSPAM.geocities.com> writes:

>     I
> Has anyone done anything like this?

Not directly, but I've got a similar application which runs an
embedded Python script in the background while my main C threads run.
It also also routes stdout/stderr from the Python script to my C code
for display purposes, permits another C thread to interject individual
Python commands to execute, and triggers event objects in the Python
script from a third thread when an event occurs.

The problem of course is that for you to interrupt the running/hung
thread, you need to do so from within that Python thread itself.  I'm
not sure signals would be the right approach - both because they
aren't cross platform but also I'm not sure how reliable they would be
in all cases - in particular delivery of signals outside your main thread, which is likely your C application.

While I haven't tried this yet myself, presumably you are getting
control within your C code whenever the embedded script calls any
functions you export, or at a minimum whenever any output is generated
since stdout is redirected to your functions, at that point you have C
code executing within the right context of the script's Python thread.

What happens if you just have a flag that your stdout redirection (or
some other regularly called function) checks, and if the script is
supposed to be terminated, that function generates an exception.  That
should then generate the exception to the script itself from within
the problem thread.

Of course, that assumes that the script is reaching out to your
supervisory code at some frequency where you could raise the exception
- it wouldn't protect against a "while 1: pass" loop, or a script that
protected itself and restarted the same problem on exception.

For that sort of case - and still making an educated guess here - you
can still intercept the Python interpreter by grabbing the global
interpreter lock (it's still yielding every 10 instructios or so in
that loop) from one of your other C threads, at which point I would
think you could probably shut down the interpreter entirely and
re-instantiate another one.  If you use Py_Finalize (instead of
Py_EndInterpreter) it won't care that you have that other thread still
hanging around, but you'll have to re-Py_Initialize() afterwards in
addition to beginning a new interpreter.  Just make sure that your
other C thread has a valid Python thread state allocated before
calling back into Python.

--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list