How to process SIGTERM signal gracefully?

前端 未结 7 628
刺人心
刺人心 2020-11-22 16:02

Let\'s assume we have such a trivial daemon written in python:

def mainloop():
    while True:
        # 1. do
        # 2. some
        # 3. important
              


        
7条回答
  •  迷失自我
    2020-11-22 16:34

    First, I'm not certain that you need a second thread to set the shutdown_flag.
    Why not set it directly in the SIGTERM handler?

    An alternative is to raise an exception from the SIGTERM handler, which will be propagated up the stack. Assuming you've got proper exception handling (e.g. with with/contextmanager and try: ... finally: blocks) this should be a fairly graceful shutdown, similar to if you were to Ctrl+C your program.

    Example program signals-test.py:

    #!/usr/bin/python
    
    from time import sleep
    import signal
    import sys
    
    
    def sigterm_handler(_signo, _stack_frame):
        # Raises SystemExit(0):
        sys.exit(0)
    
    if sys.argv[1] == "handle_signal":
        signal.signal(signal.SIGTERM, sigterm_handler)
    
    try:
        print "Hello"
        i = 0
        while True:
            i += 1
            print "Iteration #%i" % i
            sleep(1)
    finally:
        print "Goodbye"
    

    Now see the Ctrl+C behaviour:

    $ ./signals-test.py default
    Hello
    Iteration #1
    Iteration #2
    Iteration #3
    Iteration #4
    ^CGoodbye
    Traceback (most recent call last):
      File "./signals-test.py", line 21, in 
        sleep(1)
    KeyboardInterrupt
    $ echo $?
    1
    

    This time I send it SIGTERM after 4 iterations with kill $(ps aux | grep signals-test | awk '/python/ {print $2}'):

    $ ./signals-test.py default
    Hello
    Iteration #1
    Iteration #2
    Iteration #3
    Iteration #4
    Terminated
    $ echo $?
    143
    

    This time I enable my custom SIGTERM handler and send it SIGTERM:

    $ ./signals-test.py handle_signal
    Hello
    Iteration #1
    Iteration #2
    Iteration #3
    Iteration #4
    Goodbye
    $ echo $?
    0
    

提交回复
热议问题