将SIGINT信号委派给subprocess,然后清理并终止父进程

我有一个主python(testmain.py)脚本,使用subprocess.Popen命令执行另一个python脚本(test.py)。 当我按下Ctrl-C时,我希望孩退出退出代码2,然后父母显示退出代码,然后终止。

我有父和子脚本中的信号处理程序。

testmain.py

def signal_handler(signal, frame): print "outer signal handler" exit(2) signal.signal(signal.SIGINT, signal_handler) def execute() proc=subprocess.Popen("python test.py",shell=True) streamdata=proc.communicate()[0] rc=proc.returncode print "return code:",rc execute() 

test.py

 def signal_handler(signal, frame): print "exiting: inner function" exit(2) signal.signal(signal.SIGINT, signal_handler) 

我检查委托信号处理到Python中的一个subprocess是有点类似于我的问题,但在这种情况下,父母继续它的执行,我不想要的。

我想要:1.退出test.py退出(2)2.print退出代码在testmain.py 3.退出test.py退出(2)

有人可以提供build议吗? 谢谢。

更新:处理信号只在子(test.py)和检查父母(testmain.py)中的返回代码将做我想要的。

 if rc==2: print "child was terminated" exit(2) 

但我想知道是否有一个干净的方式来做到这一点使用信号处理。

你的子进程不应该在意父母是干什么的,也就是说,如果你希望孩子以Ctrl + C的特定状态退出,那么就这样做:

 import sys try: main() except KeyboardInterrupt: # use default SIGINT handler sys.exit(2) 

或者你可以明确地定义信号处理程序:

 import os import signal def signal_handler(signal, frame): os.write(1, b"outer signal handler\n") os._exit(2) signal.signal(signal.SIGINT, signal_handler) main() 

如果有多个处理器和/或多个线程,则行为可能会有所不同。

不相关的:根据你的main()函数的作用,在Python中处理一个信号之前可能会有一个明显的延迟。 Python 2上的一些阻塞方法可能会完全忽略信号:使用Python 3或为特定情况应用自定义解决方法,例如对于某些调用使用超时参数。


您可以在父级中以类似的方式处理SIGINT

 for cmd in commands: process = Popen(cmd) try: process.wait() except KeyboardInterrupt: # child process may still be alive here for _ in range(5): # wait a while if process.poll() is not None: break # the process is dead time.sleep(.1) else: # no break, kill the process explicitly try: process.kill() except OSError: pass sys.exit("Child exited with %d" % process.wait()) 

Python 2不会为子进程恢复信号,例如,如果您在父节点中SIG_IGN SIGINT信号,则可以使用preexec_fn参数明确地重置必要的hanlders 。