Python Windows上的子进程未接收到信号(SIGTERM)
我有一个启动子进程的服务器,我可以设法执行Python Windows上的子进程未接收到信号(SIGTERM),python,windows,python-3.x,subprocess,signals,Python,Windows,Python 3.x,Subprocess,Signals,我有一个启动子进程的服务器,我可以设法执行发送信号(SIGTERM),这将终止进程。但并不优雅。 如果我从shell调用我的子进程(即作为单个进程),那么定义的信号处理程序将正常地启动和退出 server.py: (因此..我首先从另一个脚本调用start\u app(),然后调用exit\u app() app.py def exit_signal_handler(signal, frame): print("Terminate signal received") app.ex
发送信号(SIGTERM)
,这将终止进程。但并不优雅。
如果我从shell调用我的子进程(即作为单个进程),那么定义的信号处理程序将正常地启动和退出
server.py:
(因此..我首先从另一个脚本调用start\u app()
,然后调用exit\u app()
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
信号,我会收到一个跟踪终止信号,应用程序关闭。
但当服务器启动app.py,我在服务器中调用exit\u app
时,我会得到一个跟踪子进程处于活动状态(来自server.py),app被终止,但信号没有在app的signalhandlerexit\u signal\u 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))
这可能回答了我的问题,但我会让它打开…当您使用Windows时,SIGTERM
处理程序是,更多:
在Windows上,C运行时实现标准C所需的六个信号:SIGINT、SIGABRT、SIGTERM、SIGSEGV、SIGILL和SIGFPE
SIGABRT和SIGTERM仅针对当前流程实现
但是您可以使用signal.CTRL\u BREAK\u事件作为
例如,在app.py中创建一个信号处理程序,该处理程序处理SIGBREAK
,但从父进程发送CTRL\u BREAK\u事件
。此外,确保使用creationflags=subprocess启动子进程。创建新的\u进程组
(否则它也会杀死父进程)
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
@georgexsh killed=已完成,已退出,进程不再在CPU上运行。和poll()
只是在发送SIGTERM
之前进行一次理智检查,以查看子进程是否确实处于活动状态,所以真正的问题是您还没有看到信号处理程序应该打印出来的消息?请尝试改为写入文件?@georgexsh hmm…这一点很好。我知道您要做什么,但\uu main\uuuuu
中发生的事情会被忽略作为subprocess()
运行时打印。我在那里也有print()
,但这里没有包含它。您可以通过将日志写入文件来确认这一点,并检查app.poll()的返回值
为0或-15,0表示正常退出,信号处理程序正常工作。通过新编辑,您使用的是windows吗?可能我不清楚,可能会编辑问题。在这两种情况下,应用程序都由SIGTERM
终止,但当作为子进程运行时,app.py中的信号处理程序不会被调用…应用程序只是终止ptlyNice引用。问题是,如果我注册SIGINT
并在键盘上按ctrl+c,我的处理程序会捕捉到信号…但当作为子进程运行时,我无法从脚本发送信号,因为send\u signal(signal.SIGINT)
会抛出错误(如编辑中所示)。你为什么使用SIGINT
?啊哈…你注册SIGBREAK
,但发送CTRL\u BREAK\u事件
谢谢!除了CTRL\u C\u事件
+SIGBREAK
,这个创建标志=子流程。创建新流程组
是关键,没有它也会杀死父进程。
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)
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