Pythonic clean Ctrl-C loop termination?

Bengt Richter bokr at oz.net
Sun Jun 23 22:25:52 EDT 2002


Wondering if this is safe, and/or if there's a more Pythonic(tm) way to do it:
(also wondering how signal.signal etc. plays in embedded interpeter contexts)

--
import signal
class SigHandler:
    def __init__(self):
        self.signaled = 0
    def __call__(self, sn, sf):
        self.signaled += 1

sh = SigHandler()
oldHandler = signal.signal(signal.SIGINT,sh)

# the idea is loop until Ctrl-C
while not sh.signaled:
    # whatever ...
# may one assume loop code 'whatever' has completed as if undisturbed here?

signal.signal(signal.SIGINT,oldHandler)
--

>From the point of view of the handler, what is the granularity of the interrupt? A byte code?
A line? A statement? A code block? Or what is "atomic"?
.../Python22/Doc/lib/module-signal.html says

"Although Python signal handlers are called asynchronously as far as the Python user is concerned,
they can only occur between the ``atomic'' instructions of the Python interpreter. This means that
signals arriving during long calculations implemented purely in C (such as regular expression matches
on large bodies of text) may be delayed for an arbitrary amount of time. "

E.g., what happens in an extension C function that is ignoring interrupt issues? Does it get suspended
while an interpreter instance or thread goes to execute the handler? From the above, apparently not.

But what happens if an extension is running python code via embedding? How would a handler in the
parent python code get control? Does any single handler globally prevent an interrupt from being
turned into a KeyboardInterrupt exception? Or will the embedded python code see an exception and
the handler in the outer context never see anything? If a single handler from any context causes
queing of the handling until the particular context is re-entered, then I guess embedded Python code
would not see anything, and there would just be a long delay until it got done, and the first
context was returned to. Probably the way it should work? Also, if the embedded code called signal.signal()
to set its own handler, IWT that should take precedence. But it would have to restore the other handler,
unless there's some magic cleanup when leaving embedded interpreting?

I guess I could experiment, but I guess someone's been there and/or there's another writeup somewhere?

Regards,
Bengt Richter



More information about the Python-list mailing list