【问题标题】:Python parent process is not catching SIGTERM/SIGINT signals when launching subprocess using os.sytem()使用 os.system() 启动子进程时,Python 父进程未捕获 SIGTERM/SIGINT 信号
【发布时间】:2017-08-22 16:10:42
【问题描述】:

我有两个 python 脚本如下 -

父.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)  

如果我运行 parent.py 并在终端上按 ctrl + c,则子进程退出并由父进程重新启动,因为父进程未处理 SIGINT 未由父进程处理。如果在终端上按下 ctrl + c,我想终止父母和孩子。但是对于孩子因为一些错误而不是 ctrl + c 事件而退出的情况,我希望父母继续执行。我本可以在父级中处理 SIGCHLD ,但这并不表明子级是否由于 ctrl + c 事件或其他原因而退出。我将如何实现这种行为?

下面是我运行父级时得到的输出 -

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
............................
............................

【问题讨论】:

    标签: python subprocess signals os.system


    【解决方案1】:

    我认为subprocess 的运气会比os.system 好。特别是,我认为您会希望将subprocessshell=False 一起使用,这样您的子命令就可以在没有子shell 的情况下执行(这可能会干扰您处理这类信号处理场景的能力)。

    如果我理解正确,下面的代码可以满足您的需求:CTRL-C 会导致子进程和父进程都停止;但是如果孩子因其他原因死亡,父母会再次运行孩子。

    这是一个类似于你的父程序:

    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'
    

    这是一个子程序,它运行了一段时间,然后因 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)
    

    【讨论】:

    • 感谢您的回答 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 2018-04-28
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多