【发布时间】:2020-11-28 16:51:27
【问题描述】:
我需要执行一些用不同 js 文件编写的代码。我在 child_process 模块中使用 fork 方法。在单个 API 调用中将有多达 1000 个请求来执行该文件代码。有了这么多的请求,杀死正在执行子文件的进程就变得很重要了。
我的查询是:
- fork 方法生成的子进程是在执行代码后自行杀死还是我们必须显式杀死它们(如果是,我们如何实现)
fork 和 childprocess 中有很多问题和答案,但 NodeJS 没有,我无法从这些答案中获得任何帮助。
以我有限的知识,我编写了示例代码并试图杀死在子节点中运行的进程。这适用于第一个 API 请求,但是当第二个 API 请求到来时。节点应用程序崩溃。
我的代码:
master.js
const fork = require('child_process').fork;
const cp1 = fork('./child1.js');
const app = require('express')();
function timer(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
app.get('/forktesting',(req, res)=>{
let num = [45, 5, 48, 91, 74, 3, 82];
try {
for (let index = 0; index < num.length; index++) {
await timer(1000);
cp1.send('test');
}
cp1.on('message', (msg)=>{
console.log(`recieving message code in parent process: ${msg.val}`);
});
cp1.on('exit',(msg=>{
console.log(`recieving exit code in parent process: ${msg}`);
}));
console.log('last line of API call');
} catch (error) {
console.log({'error' : error});
res.send({"code": 500, "status":"error"});
}
});
app.listen(8081, ()=>{ console.log(`listening to 8081`);})
child1.js
process.on('message', async(message)=>{
console.log(`in message child: ${message}`);
setTimeout(() => {
process.send({ val: "from child"});
console.log(`child pid: ${process.pid}`);
process.kill(process.pid);
}, 5000);
})
注意:显示正确的实现将非常有帮助
在第二个文件(child1.js)中,我正在调用不同的系统并等待它们的响应,收到响应后我会将其发送到父进程。
Edit2:在 cp1.send() 周围添加了 for 循环,以表明通过单个 API 调用将有多个子进程的分叉,并添加了 try catch 块。 我根据实际场景的需要添加了 for 循环进行分叉。所以同一个文件会被分叉很多次,我已经在数组中显示了 3 个项目,但之后会是 1000 个,这将从 DB 中获取。场景是:每次调用 API 时,我都必须 fork 多次,并且该 API 会被用户频繁使用,因此会有多个用户访问它。随着每个 API 命中,将添加侦听器,因此我的许多侦听器将听到单个响应,这也会在侦听器计数的某个阈值超过之后产生问题。所以,event.once 的实现会很好,但我希望孩子的响应计数也因此可能必须与监听器一起去监听每个分叉孩子的响应。
Edit1:我在子进程中删除了process.kill(process.pid),并在 5 秒内点击了两次。我得到了两次响应,这不是我想要的功能。下图显示了控制台输出。
我应该只从那个分叉的进程中得到一个响应。使用 remove process.kill(process.pid),每次调用此 API 都会增加响应计数。
照片显示原始问题和编辑 1 的日志
【问题讨论】:
-
您不想杀死任何这些进程。完成后你想
exit子进程。 -
您只在服务器启动时分叉进程一次,而不是每个请求一次。由于您的子进程在被第一个请求杀死后停止,因此它不再可用于第二个请求。不确定您实际想要达到的目标
-
"fork 方法生成的子进程在执行代码后是否会杀死自己" - 是的,每个进程在完成时会自行停止(退出),即当它认为它是自己完成的。 (当然,这可能永远不会)。
-
"使用单个 API 调用会有多个子进程的分叉" - 不,这仍然没有发生。当服务器启动时,您只对子进程进行一次分叉,然后每当您的服务器收到请求时向它发送(多个)消息。仍然只有一个子进程,没有多个分叉,也不需要杀死任何东西。
-
"this 另有说明" - 不,它和我说的完全一样。一个进程在被杀死或决定退出时停止拥有,大多数 - 但不是所有 - 进程都会这样做。无论如何,您控制子进程,所以首先您需要决定 何时应该退出。除了“我正在调用不同的系统并等待他们的响应”之外,您还没有告诉我们子进程应该做什么,但这并没有t 需要一个子进程本身。
标签: javascript node.js