信号(SIGTERM)不被Windows上的subprocess接收

我有一个服务器,启动一个subprocess,我可以设法做一个send_signal(SIGTERM)这将杀死进程。 但不够优雅。 如果我从shell调用我的subprocess(即作为一个进程),定义的信号处理程序将踢入并正常退出。

server.py:(所以..从另一个脚本我第一次调用start_app() ,然后exit_app()

 def start_app(): app = subprocess.Popen("python app.py") def exit_app(): p = app.poll() if p==None: print("Subprocess is alive") # debug app.send_signal(signal.SIGTERM) 

app.py

 def exit_signal_handler(signal, frame): print("Terminate signal received") app.exit() if __name__ == '__main__': app = QApplication(sys.argv) signal.signal(signal.SIGTERM, exit_signal_handler) signal.signal(signal.SIGINT, exit_signal_handler) sys.exit(app.exec()) 

再次,如果我从shell调用app.py并发送一个SIGTERM信号,我会Terminate signal received跟踪Terminate signal received并closures应用程序。 但是,当app.py由服务器启动,我打电话exit_app服务器中的exit_app ,我得到一个跟踪Subprocess is alive (从server.py),应用程序被杀害,但信号不捕获应用程序的signalhandler exit_signal_handler

编辑:看来send_signal()不会发送信号subprocess捕获信号的意义上。 它发送了一个信号在子过程中发生的行为:

  def send_signal(self, sig): """Send a signal to the process """ if sig == signal.SIGTERM: self.terminate() elif sig == signal.CTRL_C_EVENT: os.kill(self.pid, signal.CTRL_C_EVENT) elif sig == signal.CTRL_BREAK_EVENT: os.kill(self.pid, signal.CTRL_BREAK_EVENT) else: raise ValueError("Unsupported signal: {}".format(sig)) 

这可能回答我的问题,但我会打开它…

正如你使用Windows, SIGTERM处理程序是无用的 ,更多的参考 :

在Windows上,C运行库实现了标准C:SIGINT,SIGABRT,SIGTERM,SIGSEGV,SIGILL和SIGFPE所需的六个信号。

SIGABRT和SIGTERM仅适用于当前进程。

但是,您可以使用signal.CTRL_BREAK_EVENT作为替代 。

即在app.py中创建一个处理SIGBREAK的信号处理程序,但是从父级发送CTRL_BREAK_EVENT 。 另外,确保使用creationflags=subprocess.CREATE_NEW_PROCESS_GROUP启动你的子creationflags=subprocess.CREATE_NEW_PROCESS_GROUP (否则它也会杀死父进程)

 app = subprocess.Popen("python app.py", shell=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) time.sleep(1) while 1: p = app.poll() if p is not None: break app.send_signal(signal.CTRL_BREAK_EVENT) time.sleep(2) 

app.py:

 exit = False def exit_signal_handler(signal, frame): global exit print("Terminate signal received") exit = True signal.signal(signal.SIGBREAK, exit_signal_handler) while not exit: pass