Register SIGTEM handler only for parent process

Question:

I have the following program(this is replicated version of a complex program, but pretty much covers my problem statement).

A SIGTERM handler is registered before spanning the new process. I am unable to find a way to restraint the child process from inheriting this handler. I want to do some cleanup activities, but only once for the parent. That said, child process should not have any SIGTERM handlers.

One way might be to overwrite the sigterm handler(after process spawn) and not do anything there. But that seems a redundant code. Can someone help exploring other ways to do this.

from multiprocessing import Process
import signal
import os
import time
import psutil


def terminateChildProcesses():
    """
    Terminate all child processes
    """
    current = psutil.Process()
    children = current.children(recursive=True)

    for child in children:
        print "Terminating %s: %s" % (child.pid, ''.join(child.cmdline()))
        child.terminate()


def target():
    time.sleep(100)


if __name__ == "__main__":
    def handle_sigterm(*a):
        print "I am handled: {}".format(os.getpid())

        # terminate child processes
        terminateChildProcesses()
        os.kill(os.getpid(), 9)


    signal.signal(signal.SIGTERM, handle_sigterm)

    p = Process(target=target)
    p.start()

    target()
Asked By: Barun Sharma

||

Answers:

As far as I think, you can use multiprocessing.current_process() to conditionally register this handler:

from multiprocessing import current_process

if current_process().name == 'MainProcess':
    signal.signal(signal.SIGTERM, handle_sigterm)
Answered By: Sraw

Starting with Python 3.7, you can also use os.register_at_fork() to restore the previous handler:

import os
import signal

handler = signal.signal(signal.SIGTERM, handle_sigterm)
os.register_at_fork(after_in_child=lambda: signal.signal(signal.SIGTERM, handler))

Answered By: Jean-Charles Bertin