问题
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?
回答1:
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):
import sys
import signal
import atexit
def release():
print "Release resources..."
def sigHandler(signo, frame):
sys.exit(0)
if __name__ == "__main__":
atexit.register(release)
signal.signal(signal.SIGTERM, sigHandler)
while True:
pass
I've checked release()
is called once and only once in case of both TERM
(issued externally) and INTR
signals (Ctrl-C
from keyboard). If you need, you may install more signal handlers (e.g. for HUP
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 of SIGKILL
you won't get a chance to cleanly release resources) or simply make your application be ACID.
来源:https://stackoverflow.com/questions/23468042/the-invocation-of-signal-handler-and-atexit-handler-in-python