我想在一段特定的时间后杀死叉子。但是,在我的代码库中,我有时会收到以下错误(仅限在Windows上):
events.js:85
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at exports._errnoException (util.js:746:11)
at ChildProcess.target._send (child_process.js:484:28)
at ChildProcess.target.send (child_process.js:416:12)
at sendHelper (cluster.js:676:8)
at send (cluster.js:512:5)
at cluster.js:488:7
at SharedHandle.add (cluster.js:99:3)
at queryServer (cluster.js:480:12)
at Worker.onmessage (cluster.js:438:7)
at ChildProcess.<anonymous> (cluster.js:692:8)
这个错误似乎发生在工人尚未完全启动并被杀死时(例如需要1秒才能启动并在开始之前被杀死)
这是一个最小的示例,以便您可以重现。
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
var workers=[];
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
workers[i] = cluster.fork();
console.log('forking');
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
setTimeout(function(){
workers.forEach(function(worker){
worker.kill();
})
},1)
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}
如果我将http.createServer
更改为console.log
之类的内容,我就不会遇到问题,所以我怀疑是因为我的工作人员还没有完成&#34;开始&#34} #34;
奇怪的是,我有时会得到一个AssertionError
(它们似乎不是任何一种模式,我有时会连续10次出现相同的错误,有时它会在两个错误:在EPIPE和ASSERTION错误之间似乎是随机的。)
assert.js:86
throw new assert.AssertionError({
^
AssertionError: Resource leak detected.
at removeWorker (cluster.js:346:9)
at ChildProcess.<anonymous> (cluster.js:366:34)
at ChildProcess.g (events.js:199:16)
at ChildProcess.emit (events.js:110:17)
at Process.ChildProcess._handle.onexit (child_process.js:1074:12)
答案 0 :(得分:2)
错误的原因是守护进程在发送SIGTERM信号时还没有收听:
解决方法是在杀死fork之前等待listening
事件。
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
var workers=[];
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
workers[i] = cluster.fork();
console.log('forking');
}
cluster.on('listening', function(worker, code, signal) {
setTimeout(function(){
worker.kill();
},1)
});
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}
答案 1 :(得分:0)
这是我的解决方法...... 正如edi9999所说的那样,工作人员进程忙碌,你不能在不听的时候杀掉它。
因此,不是从主进程中杀死worker,而是从主进程向worker发送一条消息,并在worker中使用process.exit()
语句来自杀。
通过这种方式,工作人员可以完成当前的工作并从主进程中收听消息并自行终止。
<强>更新强>
在我的Repository中,您可以尝试使用示例代码。这是一个命令行工具。如果您进入该文件夹并键入node se
并按Enter键。您将获得有关如何使用它的说明。
如果你只是想看代码。同时查看以下两个文件。
1. se.js
2. functions.js