Python – The atexit handler does not respond to signals

The atexit handler does not respond to signals… here is a solution to the problem.

The atexit handler does not respond to signals

I have two python files:

a.py:

import subprocess, time, os, signal

myprocess = subprocess. Popen("b.py", shell=True)
time.sleep(2)
os.kill(myprocess.pid, signal. SIGTERM)

b.py:

import atexit

def cleanup():
    print "Cleaning up things before the program exits..."

atexit.register(cleanup)

print "Hello world!"

while True:
    pass

a.py is spawning b.py and terminates the process after 2 seconds. The problem is that I want the cleanup function to call b.py before it’s killed, but I can’t get it to work.

I ALSO TRIED SIGKILL AND SIGINT IN THE OS.KILL FUNCTION, BUT NEITHER WORKED FOR ME.

Current output (a.py):

Hello, World!
(2 seconds later, program ends)

Expected output (a.py):

Hello, World!
(2 seconds later)
Cleaning up things before the program exits...
(program ends)

Solution

Use a different signal for the Windows platform: signal. CTRL_C_EVENT

Put a little more sleep in the a.py, otherwise the child process won’t have a chance to clean up before the parent process exits:

import subprocess, time, os, signal
myprocess = subprocess. Popen("b.py", shell=True)
time.sleep(2)
os.kill(myprocess.pid, signal. CTRL_C_EVENT)
time.sleep(2)

If you don’t actually need shell functionality, I would also like to discourage you from using shell:

import subprocess, time, os, signal, sys
myprocess = subprocess. Popen([sys.executable, "b.py"])

Linux/macOS user: signal. CTRL_C_EVENT does not exist, you need signal. SIGINT

Related Problems and Solutions