我有一个带有一个父级的体系结构,它产生了两个子级(一个在c++中,另一个在python中(。父类生成以下类:
export class subProcess {
protected cmd: string;
protected args: string[];
protected process: child.ChildProcess;
constructor(cmd: string, args: string[]) {
this.cmd = cmd;
this.args = args;
this.process = null;
}
spawn(): void {
this.process = child.spawn(this.cmd, this.args);
const rlout = readline.createInterface({
input: this.process.stdout,
});
rlout.on('line', line => this.logger.info(line));
const rlerr = readline.createInterface({
input: this.process.stderr,
});
rlerr.on('line', line => this.logger.error(line));
this.process.on('exit', (code: number) => {
this.logger.info(`exit code: ${code}`);
});
}
当我用Ctrl-C中断父进程时,信号SIGINT
在父进程中能够首先断开连接并优雅地杀死子进程:
process.on('SIGINT', () => {
this.bus.disconnect();
});
disconnect
是一个通过ZeroMQ向子级发送"exit_process"
命令的函数。此命令在正常行为中运行良好。但问题是,当我按下Ctrl-C时,SIGINT
被Parent引起,它执行disconnect
函数(正如预期的那样(,但它似乎也将SIGINT
传播到了子级。事实上,通过ZeroMQ发送的"exit_process"
命令达到超时(这意味着子级从未接收/应答(,而子级通过exit
事件发出返回代码。
关键是,由于项目原因,我不能分离和/或取消引用子项,也不能管理子项中的信号。我希望父母在不将SIGINT
传播给孩子的情况下捕捉到它。
还有一点,我试图在subProcess
类中添加以下内容,但没有成功:
this.process.on('SIGINT', () => {
console.log('SIGINT received. Do nothing');
});
您的SIGINT
正在传递给整个流程组——请参阅维基百科上的这一部分。但是,由于子进程管道是如何建立的,您可能看不到任何输出。
生成新的子进程时,可以提供stdio
选项:
this.process = child.spawn(this.cmd, this.args, {stdio: 'inherit'});
以上导致父进程的process.stdin
、process.stdout
、process.stderr
由子进程继承。如果你使用这种方法,你会看到你的孩子正在接受SIGINT
。
默认行为是创建单独的流,这就是为什么您看不到console.log
。您还可以监听孩子的stdout流:
this.process.stdout.on('data', data => console.log(data.toString()));