我有一个服务器,启动了一个子进程。我可以通过
server.py: (所以,从另一个脚本中,我首先调用
再次说明,如果我从shell中调用app.py并发送
编辑: 似乎
这可能回答了我的问题,但我会让它保持开放状态...
send_signal(SIGTERM)
来杀死该进程,但是不够优雅。
如果我从shell中调用子进程(即作为单个进程),则定义的信号处理程序将会触发并优雅地退出。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
,然后app关闭。但是当app.py由服务器启动并且我在服务器中调用exit_app
时,我会得到一个跟踪信息Subprocess is alive
(来自server.py),app被杀死,但信号没有被捕获在app的信号处理程序exit_signal_handler
中。编辑: 似乎
send_signal()
并没有向子进程发送信号,以至于子进程能够捕获该信号。它向子进程发送一个信号,以执行某个操作: 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))
这可能回答了我的问题,但我会让它保持开放状态...
poll()
只是为了检查子进程是否真的还活着,然后才发送SIGTERM
。 - niCk cAMel__main__
中发生的事情在以subprocess()
方式运行时会被打印出来。我也在那里使用了print()
,只是这里没有包含它。 - niCk cAMelapp.poll()
的返回值是否为0或-15来确认此操作,其中0表示正常退出且信号处理程序正常工作。 - georgexshsignal.send_signal()
例程的复制粘贴。是的,Windows系统。 - niCk cAMel