Detect console close

Duncan Booth duncan.booth at invalid.invalid
Mon May 16 06:12:59 EDT 2005


Peter Hansen wrote:

> new pip wrote:
>> Actually I want to do some clean up (or operation) before the program
>> actually exits. Is there any way to do that?
> 
> Ah, that's easier. :-)
> 
> It might help (if this answer isn't sufficient) to post a snippet of 
> code showing a very small example that we could talk about.  You might 
> have a "special" situation, something unusual you aren't telling us 
> about yet.  (Also, mentioning your platform and versions is always a 
> good idea, but maybe not relevant in this case.)
> 
> There are a few options:
> 
> 1. "import atexit" and use that standard library module's features.
> 
> 2. put a "try/finally" block around the bulk of your code, with cleanup 
> code in the "finally" clause
> 
> 3. Just stick the cleanup code at the end of your module...  (this one 
> is too obvious, so if neither of the above answers work for you, and 
> this one is insufficient, please post example code so we know where you 
> are...)
> 

None of these work when a console running a Python script is simply closed. 
If you do that then the Python script will be terminated without running 
any cleanup code. On windows the same thing also happens if you use Ctrl-
Break to terminate the script, again it will exit without doing any 
cleanup.

You can arrange to catch when the console window is closed, but there are 
numerous things you have to watch out for if you do. The simplest thing is 
to do:

import signal
signal.signal(signal.SIGBREAK, signal.default_int_handler)

This will make the window close or ctrl-break raise a KeyboardInterrupt 
exception instead of terminating the program. You can handle this as for 
any other exception, but if you don't exit the program pretty quickly the 
user will see a popup box offering to use 'end task' to terminate your 
program with extreme prejudice.

Alternatively you can set a specific signal handler for SIGBREAK. The 
SIGBREAK handler will always be triggered on the program's main thread.

If your script is blocked for some reason (e.g. in raw_input or reading 
from a network socket) then the exception won't be raised until the 
blocking call returns, by which time the user may have already decided to 
terminate your unresponsive program. The only way I know to avoid this is 
to ensure that the signal gets raised on a different thread than the one 
which blocks. Since the signal always gets raised on the program's primary 
thread, this means you have to ensure that all keyboard input or network 
traffic happens on a secondary thread and you will have to take special 
care over cleanup code which uses any objects that thread might also be 
using.



More information about the Python-list mailing list