Python parent process is not catching SIGTERM/SIGINT signals when launching subprocess using os.sytem()

亡梦爱人 提交于 2021-02-10 14:38:20

问题


I have two python scripts as below -

parent.py

import os
import signal


shutdown = False

def sigterm_handler(signum, frame):
    global shutdown
    shutdown = True

if __name__ == '__main__':
    signal.signal(signal.SIGTERM, sigterm_handler)
    signal.signal(signal.SIGINT, sigterm_handler)
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    cmd = 'python child.py'
    while True:
        if shutdown == True:
            break
        print 'executing %s' % cmd
        exit_code = os.system(cmd)
        print 'Exit Code from %s > %s' % (cmd, exit_code)    
    print 'Exiting Parent'    

child.py

import signal
import time

shutdown = False

def sigterm_handler(signum, frame):
    global shutdown
    shutdown = True

if __name__ == '__main__':
    signal.signal(signal.SIGTERM, sigterm_handler)
    signal.signal(signal.SIGINT, sigterm_handler)
    while True:
        if shutdown == True:
            break
        print 'Child Process Running !!'
        time.sleep(1)  

If I run parent.py and press ctrl + c on the terminal the child process exits and gets restarted by the parent as the parent is not processing the SIGINT is not being processed by the parent. I want to terminate both parent and the child if ctrl + c is pressed on the terminal. But for cases where the child exits because of some error instead of ctrl + c event, I want the parent to continue executing. I could have handled SIGCHLD in the parent but that doesn't indicate if the child was exited because of a ctrl + c event or something else. How would I achieve this behavior ?

below is the output I get if I run the parent -

executing python child.py
Child Process Running !!
Child Process Running !!
Child Process Running !!
Child Process Running !!
^CExit Code from python child.py > 2
executing python child.py
Child Process Running !!
Child Process Running !!
Child Process Running !!
Child Process Running !!
Child Process Running !!
^CExit Code from python child.py > 2
executing python child.py
Child Process Running !!
Child Process Running !!
Child Process Running !!
Child Process Running !!
^CExit Code from python child.py > 2
............................
............................

回答1:


I think you'll have better luck with subprocess than os.system. In particular, I think you'll want to use subprocess with shell=False so that your child command is executed without a subshell (which might interfere with your ability to handle these kinds of signal-handling scenarios).

The code below does what you want, if I understand you correctly: CTRL-C causes both child and parent to stop; but if child dies for some other reason, parent will run the child again.

Here's a parent program similar to yours:

import signal
import subprocess

shutdown = False

def sigterm_handler(signum, frame):
    print 'parent got shutdown'
    global shutdown
    shutdown = True

if __name__ == '__main__':
    signal.signal(signal.SIGTERM, sigterm_handler)
    signal.signal(signal.SIGINT, sigterm_handler)
    cmd_args = ['python', 'child.py']
    while not shutdown:
        print 'executing', cmd_args
        try:
            subprocess.check_call(cmd_args)
        except subprocess.CalledProcessError:
            print 'child died'
            pass
    print 'Exiting Parent'

And here is a child program that runs for a while and then dies with a ZeroDivisionError.

import signal
import sys
import time

def sigterm_handler(signum, frame):
    print 'child got shutdown'
    sys.exit(0)

if __name__ == '__main__':
    signal.signal(signal.SIGTERM, sigterm_handler)
    signal.signal(signal.SIGINT, sigterm_handler)
    for i in range(3, -1, -1):
        print 'Child Process Running', i, i/i
        time.sleep(3)


来源:https://stackoverflow.com/questions/43088987/python-parent-process-is-not-catching-sigterm-sigint-signals-when-launching-subp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!