如何管理已分叉的多个并发子进程?管理多个节点子进程
在此示例中,可以多次调用start_child()
,并且每个调用都可以无限期地运行。当像这样分配任意数量的子进程时,如何与每个子进程通信/处理?假设我有3个分叉的子进程正在运行,并且它们会一直运行,但我想要杀死(或发送消息)到子进程号2.我该怎么做?
如果调用stop_child()
,它会杀死所有当前正在运行的子进程。如何重构此代码,以便我可以在个别子进程上调用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
}
UPDATE
我想这一点,基于一些评论。但是,如果我启动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()
调用似乎没有做任何事情)是由我遗漏的一段代码引起的(在代码注释中:'条件逻辑再次运行start_child()或让它结束')。
这是什么在那里:
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');
}
什么操作系统是服务器上运行的,什么是你的child_script做。它在'child.kill()'doc的文档中说过:***请注意,虽然函数被称为kill,但传递给子进程的信号可能不会真正终止进程。***您还应该记录' child.on('error',...)'如果传递kill消息时发生错误。 – jfriend00
目前,它运行在Windows上的Cygwin环境中。 – CJG