robust clean-up with SIGTERM (was Re: Again, how to write a cleanup function for a module in C )

Jane Austine janeaustine50 at hotmail.com
Wed Aug 13 14:51:31 EDT 2003


I'm writing a cgi script. The user can push the stop button at any
moment while the page is loading, and the apache will raise SIGTERM
and then SIGKILL in 3 secs. And the garbage is not collected
automatically when the signals are raised. It's an abnormal
termination.

I need to clean up a few things(like closing the db connection) before
the interpreter terminates.

How do I?

And according to Alex's suggestions... (see my questions below)

"Alex Martelli" <aleax at aleax.it> wrote:

[snip]
> 
> Are you implying that atexit doesn't?  Run the following script:
> 
> import atexit
> def f(*args):
>     print 'f',args
> atexit.register(f,'goo','bar','baz')
> 1/0
> 
> The output I see for it is as follows:
> 
> [alex at lancelot src]$ python2.2 a.py
> Traceback (most recent call last):
>   File "a.py", line 5, in ?
>     1/0
> ZeroDivisionError: integer division or modulo by zero
> f ('goo', 'bar', 'baz')
> [alex at lancelot src]$
> 
> 
> Signals are nastier -- by default they terminate the process
> WITHOUT cleanup.  For example, if instead of the 1/0 you have
> at the end of the script:
> 
> import os, signal
> os.kill(os.getpid(), signal.SIGIO)
> 
> then f won't get run.  Easy solution (won't work all of the
> time, but, pretty often): handle the signal to turn it into
> an exception!  e.g. change the above two lines to:
> 
> import os, signal
> def sig2exc(sig, frm): raise SystemError(sig)
> signal.signal(signal.SIGIO, sig2exc)
> os.kill(os.getpid(), signal.SIGIO)
> 
> and f will again execute.
>
> 
[snip]
> 
> So, handle the signal, and make the program die "cleanly" with the
> exception of your choice -- THEN, cleanup code DOES run.
> 
[snip]

This "signal to exception translation" looks nice. But Alex said
"won't work all of the time, but, pretty often". I am afraid to use
this method if its safety is not guaranteed. I wonder in what cases it
does not work, and how I can make it work always.




More information about the Python-list mailing list