I have a piece of Python code as below:
import sys
import signal
import atexit
def release():
print "Release resources..."
def sigHandler(signo, frame):
release()
sys.exit(0)
if __name__ == "__main__":
signal.signal(signal.SIGTERM, sigHandler)
atexit.register(release)
while True:
pass
The real code is far more complex than this snippets, but the structures are the same: i.e. main function maintains an infinite loop.
I need a signal callback to release the resources occupied, like DB handle.
Then I add a SIGTERM
handler, in case the server is killed, which simply invoke the release function and then exit the process.
The atexit
one aims to handling process complete successfully.
Now I have a problem I just want release
to be invoked only once when the process is killed. Any improvement on my code?
Well, according to the documentation atexit handlers aren't executed if the program is killed by a signal not handled by Python, or in case of internal error, or if
os._exit()
is called. So I would use something like this (almost copied your code):I've checked
release()
is called once and only once in case of bothTERM
(issued externally) andINTR
signals (Ctrl-C
from keyboard). If you need, you may install more signal handlers (e.g. forHUP
etc). If you need "a more graceful shutdown", you should find a way to gracefully break the loop and/or install external "shutdown handlers" (in case ofSIGKILL
you won't get a chance to cleanly release resources) or simply make your application be ACID.