如何管理已分叉的多個併發子進程?管理多個節點子進程
在此示例中,可以多次調用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