Python parent 进程在使用 os.sytem() 启动子进程时未捕获 SIGTERM/SIGINT 信号
Python parent process is not catching SIGTERM/SIGINT signals when launching subprocess using os.sytem()
我有两个 python 脚本如下 -
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)
如果我 运行 parent.py 并在终端上按 ctrl + c,child 进程退出并由 parent 作为 parent 重新启动未处理 parent 未处理 SIGINT。如果在终端上按下 ctrl + c,我想同时终止 parent 和 child。但是对于 child 由于某些错误而不是 ctrl + c 事件而退出的情况,我希望 parent 继续执行。我本可以在 parent 中处理 SIGCHLD,但这并不表示 child 是否由于 ctrl + c 事件或其他原因而退出。我将如何实现这种行为?
下面是我 运行 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
............................
............................
我认为 subprocess
比 os.system
更幸运。特别是,我认为您会希望将 subprocess
与 shell=False
一起使用,以便您的 child 命令在没有子 shell 的情况下执行(这可能会干扰您处理此类 signal-handling 情景)。
如果我理解正确的话,下面的代码可以满足您的需求:CTRL-C 会导致 child 和 parent 停止;但如果 child 由于其他原因死亡,parent 将再次 运行 child。
这是一个与您的类似的 parent 程序:
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'
这是一个 child 程序,它 运行 运行了一段时间然后死于 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)
我有两个 python 脚本如下 -
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)
如果我 运行 parent.py 并在终端上按 ctrl + c,child 进程退出并由 parent 作为 parent 重新启动未处理 parent 未处理 SIGINT。如果在终端上按下 ctrl + c,我想同时终止 parent 和 child。但是对于 child 由于某些错误而不是 ctrl + c 事件而退出的情况,我希望 parent 继续执行。我本可以在 parent 中处理 SIGCHLD,但这并不表示 child 是否由于 ctrl + c 事件或其他原因而退出。我将如何实现这种行为?
下面是我 运行 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
............................
............................
我认为 subprocess
比 os.system
更幸运。特别是,我认为您会希望将 subprocess
与 shell=False
一起使用,以便您的 child 命令在没有子 shell 的情况下执行(这可能会干扰您处理此类 signal-handling 情景)。
如果我理解正确的话,下面的代码可以满足您的需求:CTRL-C 会导致 child 和 parent 停止;但如果 child 由于其他原因死亡,parent 将再次 运行 child。
这是一个与您的类似的 parent 程序:
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'
这是一个 child 程序,它 运行 运行了一段时间然后死于 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)