Python: What is the default handling of SIGTERM?
Asked Answered
L

3

50

What does Python do under the covers by default if it receives a SIGTERM but there is no signal handler registered for it?

Lacefield answered 29/3, 2012 at 17:42 Comment(2)
Sorry to say that the bounty here has been wasted, as nothing changed and Thomas Wouters' answer is still correct for current Python versions, including 3.6 and 3.7.Fusty
Terminate an interruption of signals.Guanine
H
38

Building on the answer of Thomas Wouters, python does not register a handler for the SIGTERM signal. We can see this by doing:

In[23]: signal.SIG_DFL == signal.signal(signal.SIGTERM,signal.SIG_DFL)
Out[23]: True

That means that the system will take the default action. On linux, the default action (according to the signal man page) for a SIGTERM is to terminate the process.

Terminating a process means that:

  • the process will simply not be allocated any more time slices during which it can execute code.

    • This means that it will not raise an exception, or call the code in try: finally: blocks, or the __exit__ method of context managers. It will not do those things because that particular python interpreter will never get the chance to execute another instruction.
  • The process's memory and other resources (open files, network sockets, etc...) will be released back to the rest of the system.

Horatius answered 24/1, 2017 at 23:25 Comment(1)
This is so true, important and - at least to me - unintuitive. I thought the whole business of finally clauses and _exit_ methods of context-managers was to make sure the code in question is always run (except a SIGKILL, which I was aware of is handled on a system level). Struggled several days with this and only now came to the realization that you already presented here in your answer. I need to keep this in mind.Garber
N
25

Nothing. Python itself does not register a signal handler for it. You can check this in the interactive interpreter:

>>> import signal
>>> signal.signal(signal.SIGTERM, signal.SIG_DFL)
0
>>> signal.SIG_DFL
0

That shows signal.signal() returning signal.SIG_DFL for signal.SIGTERM. Contrast it with signal.SIGINT, which does have a default signal handler (which raises KeyboardInterrupt):

>>> signal.signal(signal.SIGINT, signal.SIG_DFL)
<built-in function default_int_handler>
Namecalling answered 29/3, 2012 at 18:0 Comment(4)
This also means that functions registered via atexit.register() won't be called if the process is terminated by SIGTERM.Leisha
Ok fine, but what does it DO? Exit uncleanly? Ignore it completely? Something else?Machellemachete
Immediately dies. Python just completely ignores the signal, and therefore dies immediately. Python does not "do" anything. That's my own reading/understanding of what people are saying above. Someone can feel free to chime in and correct me if I've misunderstood.Majestic
(presumably however, we could register our own handler that does raise a normal exception?)Majestic
T
2

Look at this example:

import time

class A:
    def __init__(self):
        print("A.__init__()")

    def __del__(self):
        print("A.__del__()")

a = A()
b = A()

time.sleep(10)

Under normal circumstances, the output would be:

A.__init__()
A.__init__()
A.__del__()
A.__del__()

But if you kill it with SIGTERM you get:

A.__init__()
A.__init__()
Terminated

Thus the program does not terminate cleanly (the destructors are not called).

Triboluminescent answered 7/10, 2019 at 10:35 Comment(1)
Yes, that is the default action when a process doesn't register a SIGTERM handler. And that's what Thomas Wouters' answer tells us already, and stochastic makes explicit.Fusty

© 2022 - 2024 — McMap. All rights reserved.