您好我正在使用child_process.spwan启动在Windows上运行python脚本的子进程。脚本侦听SIGINT以优雅地退出自身。但Windows不支持信号,所有节点都在模拟。因此,Windows上的child_process.kill('SIGINT')
实际上是无条件地终止进程(没有优雅的退出,没有调用python的SIGTERM / SIGINT处理程序)。同样向stdin写一个ctrl+c
字符也不起作用。
当我查看Python API时,我得到了可以满足需要的CTRL_BREAK_EVENT和CTRL_C_EVENT。我想知道节点是否具有相同的平台特定API?
相关帖子,但没有工作: How to send control C node.js and child_processes sending crtl+c to a node.js spawned childprocess using stdin.write()?
答案 0 :(得分:1)
您可以使用IPC消息向孩子发出停止和优雅终止的时间。以下方法使用process.on('message')
来监听子进程中父节点的消息。 child_process.send()
将邮件从父级发送给孩子。
如果孩子挂起或需要很长时间才完成,下面的代码有1分钟超时设置退出。
<强> PY-脚本wrapper.js 强>
// Handle messages sent from the Parent
process.on('message', (msg) => {
if (msg.action === 'STOP') {
// Execute Graceful Termination code
process.exit(0); // Exit Process with no Errors
}
});
家长流程
const cp = require('child_process');
const py = cp.fork('./py-script-wrapper.js');
// On 'SIGINT'
process.on('SIGINT', () => {
// Send a message to the python script
py.send({ action: 'STOP' });
// Now that the child process has gracefully terminated
// exit parent process without error
py.on('exit', (code, signal) => {
process.exit(0);
});
// If the child took too long to exit
// Kill the child, and exit with a failure code
setTimeout(60000, () => {
py.kill();
process.exit(1);
});
});
答案 1 :(得分:0)
您可以通过stdin向Quhthon进程发送'quit'命令,这对我有用。在Python中,您需要创建一个使用input
从stdin读取的线程,一旦返回,您就设置了一个事件标志。在主应用程序循环中,您会定期检查事件是否已设置并退出程序。
Python应用程序(script.py):
import threading
import sys
def quit_watch(event):
input("Type enter to quit")
event.set()
def main():
stop = threading.Event()
threading.Thread(target=quit_watch, args=[stop]).start()
while True:
# do work, regularly check if stop is set
if stop.wait(1):
print("Stopping application loop")
break
if __name__ == '__main__':
main()
sys.exit(0)
Node.js应用程序:
child_process = require('child_process')
child = child_process.spawn('python.exe', ['script.py'])
// check if process is still running
assert(child.kill(0) == true)
// to terminate gracefully, write newline to stdin
child.stdin.write('\n')
// check if process terminated itself
assert(child.kill(0) == false)