I have a python service which may be ended by exception - I'm ok with it. But the problem is that it spawned an child process which continues to run even it's parent got a fail.
import multiprocessing as mp
from time import sleep
import os
import atexit
import psutil
@atexit.register # Doesn't fired at exception
def goodbye():
current_process = psutil.Process()
children = current_process.children(recursive=True)
for child in children:
print('Kill child with pid {}'.format(child.pid))
try:
child.terminate()
except:
pass
print("You are now leaving the Python sector.")
def func(): # Child process
while True:
ppid = os.getppid()
print("Parent process id:", ppid)
if ppid == 1:
print("Parent process has terminated")
break
sleep(1)
t = mp.Process(target=func, args=())
t.start()
print(9 + "0") # Exception here
print("I'm ok")
And service continues to work (formally) until it got a kick from outside:
Parent process id: 29118
Traceback (most recent call last):
File "stestcp.py", line 32, in <module>
print(9 + "0") # Exception here
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Parent process id: 29118
Parent process id: 29118
Parent process id: 29118
Parent process id: 29118
Parent process id: 29118
^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/lib/python3.6/multiprocessing/popen_fork.py", line 28, in poll
Process Process-1:
pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
Traceback (most recent call last):
File "/usr/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/usr/lib/python3.6/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "stestcp.py", line 27, in func
sleep(1)
KeyboardInterrupt
Kill child with pid 29119
You are now leaving the Python sector.
The question is - is there any way to call some global fallback function (like atexit) when program failed with exception?