niC*_*Mel 4 python windows subprocess signals python-3.x
我有一个启动子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)
Run Code Online (Sandbox Code Playgroud)
应用程序
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())
Run Code Online (Sandbox Code Playgroud)
同样,如果我从 shell 调用 app.py 并发送一个SIGTERM信号,我会得到一个跟踪Terminate signal received并关闭应用程序。但是当 app.py 由服务器启动并且我exit_app在服务器中调用时,我得到一个跟踪Subprocess is alive(来自 server.py)并且应用程序被杀死但信号没有被应用程序的信号处理程序捕获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))
Run Code Online (Sandbox Code Playgroud)
这可能回答了我的问题,但我会保持开放...
当您使用 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(否则它也会杀死父进程)
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)
Run Code Online (Sandbox Code Playgroud)
应用程序.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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5707 次 |
| 最近记录: |