杀死Windows上的叉子"写EPIPE"

时间:2015-07-23 14:08:01

标签: node.js pipe fork broken-pipe

我想在一段特定的时间后杀死叉子。但是,在我的代码库中,我有时会收到以下错误(仅限在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)

2 个答案:

答案 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

希望它有所帮助!!