Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Windows上的子进程未接收到信号(SIGTERM)_Python_Windows_Python 3.x_Subprocess_Signals - Fatal编程技术网

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的signalhandler
exit\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