在 windows 上杀死叉子抛出 "write EPIPE"
Kill fork on windows throws "write EPIPE"
我想在特定时间后杀死叉子。但是,在我的代码库中,有时会出现以下错误(仅在 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)
每当 worker 尚未完全启动并被杀死时(例如需要 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
之类的东西,我没有问题,所以我怀疑这是因为我的工人还没有完成 "starting"。
奇怪的是,我有时也会得到一个 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)
错误的原因是当我们发送 SIGTERM 信号时守护进程还没有监听:
解决方法是等待 listening
事件,然后再杀死 fork。
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);
}
这是我的解决方法...
正如 edi9999 所说,工作进程正在忙于某事,你不能在它不听的时候杀死它。
因此,与其从主进程中杀死 worker,不如从主进程向 worker 发送一条消息,并在 worker 中使用 process.exit()
语句来杀死自己。
这样,worker会完成当前的工作,监听主进程的消息,然后kill自己。
更新
在我的这个 Repository 中,有一个示例代码,您可以尝试一下。这是一个命令行工具。如果您进入该文件夹并输入 node se
并按回车键。您将获得有关如何使用它的说明。
如果你只是想看代码。同时查看以下两个文件。
1. se.js
2.functions.js
希望对您有所帮助!!
我想在特定时间后杀死叉子。但是,在我的代码库中,有时会出现以下错误(仅在 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)
每当 worker 尚未完全启动并被杀死时(例如需要 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
之类的东西,我没有问题,所以我怀疑这是因为我的工人还没有完成 "starting"。
奇怪的是,我有时也会得到一个 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)
错误的原因是当我们发送 SIGTERM 信号时守护进程还没有监听:
解决方法是等待 listening
事件,然后再杀死 fork。
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);
}
这是我的解决方法... 正如 edi9999 所说,工作进程正在忙于某事,你不能在它不听的时候杀死它。
因此,与其从主进程中杀死 worker,不如从主进程向 worker 发送一条消息,并在 worker 中使用 process.exit()
语句来杀死自己。
这样,worker会完成当前的工作,监听主进程的消息,然后kill自己。
更新
在我的这个 Repository 中,有一个示例代码,您可以尝试一下。这是一个命令行工具。如果您进入该文件夹并输入 node se
并按回车键。您将获得有关如何使用它的说明。
如果你只是想看代码。同时查看以下两个文件。
1. se.js
2.functions.js
希望对您有所帮助!!