atexit/signal for non-interactive jobs

kj no.email at please.post
Wed May 26 16:19:47 EDT 2010





I want to implement clean-up functions for scripts to be run on a
Linux cluster (through LSF).  The goal is to make sure that a
minimal wrap-up sequence (print diagnostic info, flush buffers,
etc.) gets executed if the job is terminated for some reason.  (The
most common reason for premature termination is a SIGUSR2 signal,
sent to the process by LSF when the job has taken longer than the
time limit for the job's LSF queue.)

No matter what I try, I can't get this wrap-up sequence to work
when the script runs non-interactively.

The latest I have looks something like this:

import signal
import atexit

def set_handlers(handler):
    atexit.register(handler)
    for sig in dir(signal):
        if sig.startswith('SIG') and not '_' in sig:
            signal(getattr(signal, sig), handler)

def wrapup(*args):    
    # etc, etc

def main():
    # ... 
    set_handlers(wrapup)
    run()

main()


If I start the script interactively and after a few seconds (i.e.
before it terminates) I hit Ctrl-C (which sends a TERM signal to
the process), the wrapup function gets called as desired (although
this action appears to be triggered by atexit, and not by the
handler for SIGTERM, which apparently never gets called).

But if instead I background the script after starting it, and then
use kill to explicitly send a TERM signal to its process, the script
terminates, but the wrapup code does not execute.

It makes no sense to me.  If someone cares to explain it, I'd be
very grateful.  (Is my code doing something wrong?)

But more to the point, what must I do to get this to work in the
non-interactive case?

TIA!

~k



More information about the Python-list mailing list