在Node中杀死分离的子进程

bybem2ql  于 2023-06-22  发布在  Node.js
关注(0)|答案(3)|浏览(129)

我不完全理解为什么我不能杀死一个分离的进程。有人能帮帮我吗?

    • 服务器(子进程)**
const server = spawn(
    'npm',
    [
        'run',
        'watch:be',
    ],
    {
        detached: true,
    },
);
    • 等待服务器启动并运行**
await waitOn({
    resources: [
        `https://localhost:${process.env.SERVER_PORT}`,
    ],
    delay: 1000,
    timeout: 30000,
});
console.log('server is up and running');
    • 再等几秒钟**
await new Promise((resolve, reject): void => {
    setTimeout((): void => {
        resolve();
    }, 2000);
});
console.log('Run test');
    • 关闭子服务器**
server.kill();
console.log('Shutdown server');

所有这些都在同一个文件中。
子进程打开了一个新的终端窗口(当它执行spawn时,这是预期的),但当kill时没有关闭。有人能指出我做错了什么吗?

5lhxktic

5lhxktic1#

server.kill();

根据node.js文档,subprocess.kill()方法向子进程发送信号。当您使用detached选项时,节点为子进程创建一个单独的进程组,并且它不再是同一进程的一部分。

detached <boolean>: Prepare child to run independently of its parent process

这就是当使用detached时不适合使用kill的原因。
这一点已在此处讨论:https://github.com/nodejs/node/issues/2098
正如上面的链接中所建议的,您应该使用process.kill来杀死进程(https://nodejs.org/api/process.html#process_process_kill_pid_signal)。这可能对你有用:

process.kill(-server.pid)
rwqw0loc

rwqw0loc2#

您说“子进程打开了一个新的终端窗口...”
基于此行为,您的操作系统似乎是Windows。
在Windows上,将options.detached设置为true可以使子进程在父进程退出后继续运行。子进程将有自己的控制台窗口。一旦为子进程启用,就不能禁用它。
来源
对于process.kill,第二个参数是您要发送的信号。默认情况下,此信号为SIGTERM。然而,根据Node.js文档的信号事件部分,SIGTERM似乎在Windows上不受支持。

  • 'SIGTERM'在Windows上不受支持,但可以监听。

也许试试

process.kill(server.pid, 'SIGHUP')

process.kill(server.pid, 'SIGINT')

(This在macOS上工作,但我没有在Windows上尝试过。

rta7y2nd

rta7y2nd3#

对我来说,杀死.exec()子进程唯一有效的方法是在尝试使用kill的每一个信号都不起作用后使用npm库terminate。但是terminate做到了。具体操作如下:

const terminate = require('terminate')
terminate(myProcess.pid, err => console.log(err))

其中myProcess简单地是:const myProcess = childProcess.exec(...)。您不需要在子进程上使用{ detached: true },这不是必要的。
您可以使用以下命令安装terminate:yarn add terminate
这一招非常有效。

相关问题