管理多个节点子进程
managing multiple node child processes
如何管理已分叉的多个并发子进程?
在这个例子中,start_child()
可以被多次调用,每次调用都可以运行无限期。当像这样分叉任意数量的子进程时,我如何与每个单独的子进程通信/寻址?假设我有 3 个分叉的子进程 运行ning,它们无限期地保持 运行ning,但我想杀死(或向)2 号子进程发送消息。我该怎么做?
如果调用 stop_child()
,它会终止所有当前 运行ning 子进程。如何重构此代码以便我可以在单个子进程上调用 stop_child()
?
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
let fork = require('child_process').fork;
server.listen(80);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
socket.on('start_child', function () {
start_child();
});
socket.on('stop_child', function () {
child.kill();
}
}
function start_child() {
child = fork('./child_script.js');
//conditional logic to either run
//start_child() again or let it end
}
更新
我根据一些评论试过了。但是如果我启动 3 个进程然后调用,例如 child[0].kill()
,我会得到一个错误:Cannot read property 'kill' of undefined
。我猜我的问题是我没有正确地将 i
变量传递给 io.on()
调用:
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
let fork = require('child_process').fork;
let i = 0;
let child = [];
server.listen(80);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
socket.on('start_child', function (i) {
start_child(i++);
});
//this is hard coded just for testing
socket.on('stop_child', function () {
child[0].kill();
}
}
function start_child(i) {
child[i] = fork('./child_script.js');
//conditional logic to either run
//start_child() again or let it end
}
更新#2
好的,我发现我需要从客户端发送递增变量,通过来自 emit
调用的对象传递。现在当我调用 child[0].kill()
时没有错误。问题是子进程没有被杀死:
server.js
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
let fork = require('child_process').fork;
server.listen(80);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
socket.on('start_child', function (count) {
let num = count.count;
start_child(num);
});
//this is hard coded just for testing
socket.on('stop_child', function (count) {
let num = count.count;
child[num].kill();
}
}
function start_child(num) {
child[num] = fork('./child_script.js');
//conditional logic to either run
//start_child() again or let it end
}
index.html
$(function () {
let socket = io();
let i = 0;
$('#start').on('click', function () {
socket.emit('start_child', {"count": i++});
});
$('#stop').on('click', function () {
//the count is hard coded here just for testing purposes
socket.emit('stop_child', {"count": 0});
});
});
最终更新 - 有决议
解决方案 #2(正上方)实际上是解决方案。之后我遇到的问题(child.kill()
调用似乎没有做任何事情)是由我遗漏的一段代码引起的(在代码注释中:'conditional logic to either run start_child() again or let it end')。
这是里面的内容:
if (condition) {
setTimeout(start_child, 5000);
} else {
console.log('this child process has ended');
}
这就是我将其更改为的内容(基本上,我只需要将递增变量传递给 start_child()
函数,以便它在 child
数组中具有相同的位置重新启动):
if (condition) {
setTimeout(function() {
start_child(num)
}, 5000);
} else {
console.log('this child process has ended');
}
fork()
returns 一个 ChildProcess 对象,它在该对象上具有用于与该进程进行进程间通信的方法和事件。因此,您必须在调用 start_child()
时保存每个 ChildProcess 对象,然后使用适当的对象与其他进程进行通信。
您可以看到 ChildProcess 对象的事件和方法here。还有大量的代码示例。
为了给子进程发送消息,使用下面的例子:
parent.js
**
const { fork } = require('child_process');
const forked = fork('child.js');
forked.on('message', (msg) => {
console.log('Message from child', msg);
});
forked.send({ hello: 'world' });
**
child.js
process.on('message', (msg) => {
console.log('Message from parent:', msg);
});
let counter = 0;
setInterval(() => {
process.send({ counter: counter++ });
}, 1000);
有关更多信息,请参阅这篇文章:
https://medium.freecodecamp.com/node-js-child-processes-everything-you-need-to-know-e69498fe970a
如何管理已分叉的多个并发子进程?
在这个例子中,start_child()
可以被多次调用,每次调用都可以运行无限期。当像这样分叉任意数量的子进程时,我如何与每个单独的子进程通信/寻址?假设我有 3 个分叉的子进程 运行ning,它们无限期地保持 运行ning,但我想杀死(或向)2 号子进程发送消息。我该怎么做?
如果调用 stop_child()
,它会终止所有当前 运行ning 子进程。如何重构此代码以便我可以在单个子进程上调用 stop_child()
?
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
let fork = require('child_process').fork;
server.listen(80);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
socket.on('start_child', function () {
start_child();
});
socket.on('stop_child', function () {
child.kill();
}
}
function start_child() {
child = fork('./child_script.js');
//conditional logic to either run
//start_child() again or let it end
}
更新
我根据一些评论试过了。但是如果我启动 3 个进程然后调用,例如 child[0].kill()
,我会得到一个错误:Cannot read property 'kill' of undefined
。我猜我的问题是我没有正确地将 i
变量传递给 io.on()
调用:
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
let fork = require('child_process').fork;
let i = 0;
let child = [];
server.listen(80);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
socket.on('start_child', function (i) {
start_child(i++);
});
//this is hard coded just for testing
socket.on('stop_child', function () {
child[0].kill();
}
}
function start_child(i) {
child[i] = fork('./child_script.js');
//conditional logic to either run
//start_child() again or let it end
}
更新#2
好的,我发现我需要从客户端发送递增变量,通过来自 emit
调用的对象传递。现在当我调用 child[0].kill()
时没有错误。问题是子进程没有被杀死:
server.js
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
let fork = require('child_process').fork;
server.listen(80);
app.get('/', function(request, response) {
response.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
socket.on('start_child', function (count) {
let num = count.count;
start_child(num);
});
//this is hard coded just for testing
socket.on('stop_child', function (count) {
let num = count.count;
child[num].kill();
}
}
function start_child(num) {
child[num] = fork('./child_script.js');
//conditional logic to either run
//start_child() again or let it end
}
index.html
$(function () {
let socket = io();
let i = 0;
$('#start').on('click', function () {
socket.emit('start_child', {"count": i++});
});
$('#stop').on('click', function () {
//the count is hard coded here just for testing purposes
socket.emit('stop_child', {"count": 0});
});
});
最终更新 - 有决议
解决方案 #2(正上方)实际上是解决方案。之后我遇到的问题(child.kill()
调用似乎没有做任何事情)是由我遗漏的一段代码引起的(在代码注释中:'conditional logic to either run start_child() again or let it end')。
这是里面的内容:
if (condition) {
setTimeout(start_child, 5000);
} else {
console.log('this child process has ended');
}
这就是我将其更改为的内容(基本上,我只需要将递增变量传递给 start_child()
函数,以便它在 child
数组中具有相同的位置重新启动):
if (condition) {
setTimeout(function() {
start_child(num)
}, 5000);
} else {
console.log('this child process has ended');
}
fork()
returns 一个 ChildProcess 对象,它在该对象上具有用于与该进程进行进程间通信的方法和事件。因此,您必须在调用 start_child()
时保存每个 ChildProcess 对象,然后使用适当的对象与其他进程进行通信。
您可以看到 ChildProcess 对象的事件和方法here。还有大量的代码示例。
为了给子进程发送消息,使用下面的例子:
parent.js
**
const { fork } = require('child_process');
const forked = fork('child.js');
forked.on('message', (msg) => {
console.log('Message from child', msg);
});
forked.send({ hello: 'world' });
**
child.js
process.on('message', (msg) => {
console.log('Message from parent:', msg);
});
let counter = 0;
setInterval(() => {
process.send({ counter: counter++ });
}, 1000);
有关更多信息,请参阅这篇文章:
https://medium.freecodecamp.com/node-js-child-processes-everything-you-need-to-know-e69498fe970a