Child_process抛出错误:写EPIPE

时间:2016-05-10 12:05:32

标签: javascript node.js child-process

我只是练习一些关于child_process @the link的节点js代码 我的节点版本是Windows 7上的V5.2.0。

// master.js
var cp=require("child_process");

var np=cp.fork("./console.js");               // line B

// block C
np.stdout.on("data",function(data){
   console.log("child process output:"+data);
});

np.stderr.on("data", function(err){
    console.log("child process output error:"+err);
});

np.on("close", function () {
    console.log("child process exit");
});

// end of block C



np.send({Hello:"world"});
np.on("message",function(msg){
    console.log("parent process got a msg:",msg);
});




// console.js

#!/usr/bin/env node

var aa=1;
console.log("The aa is :"+aa);


process.on("message", function (m) {
    console.log("child process got message:",m);
});

process.send({foo:"bar"});

1)我运行上面的代码,我得到了错误:写EPIPE。我用谷歌搜索,我没有找到任何有用的答案。我只是一个新的nodejs,我按照官方文档进行了一些修改,然后示例代码失败了。我发现如果我注释掉块C中的代码,示例代码就可以了。所以我想知道为什么代码抛出错误,如果np.stdout / np.stderr监听'数据'?

$ The aa is :1
events.js:142
      throw er; // Unhandled 'error' event
      ^

Error: write EPIPE
    at exports._errnoException (util.js:856:11)
    at process.target._send (internal/child_process.js:607:18)
    at process.target.send (internal/child_process.js:508:19)
    at Object.<anonymous> (D:\Practice\..\console.js:
11:9)
    at Module._compile (module.js:399:26)
    at Object.Module._extensions..js (module.js:406:10)
    at Module.load (module.js:345:32)
    at Function.Module._load (module.js:302:12)
    at Function.Module.runMain (module.js:431:10)
    at startup (node.js:141:18)

2)我修改了master.js代码,运行如下代码:

var cp=require("child_process");

var np=cp.spawn("node", ["./console.js"]);

np.send({Hello:"world"});
np.on("message",function(msg){
    console.log("parent process got a msg:",msg);
});

它会抛出错误:

np.send({Hello:"world"});
   ^

TypeError: np.send is not a function

我再次访问node js official doc,我没有发现spawn()和fork()是非常不同的。所以我想知道为什么np.send不是函数?

官方文件没有提到一些要点吗?

1 个答案:

答案 0 :(得分:5)

1 /关于np.send找不到方法

当子项被分叉或者管道设置为IPC时,

child_process.send方法可用

  

使用child_process.fork()时,您可以使用   child.send(message [,sendHandle] [,callback])和消息是   通过关于孩子的“消息”事件收到。

IPC

  

'ipc' - 创建用于传递消息/文件描述符的IPC通道   父母和孩子之间。 ChildProcess最多可以有一个IPC   stdio文件描述符。设置此选项可启用   ChildProcess.send()方法。如果孩子将JSON消息写入此   文件描述符,然后这将触发ChildProcess.on('message')。如果   子节点是Node.js程序,然后是IPC通道的存在   将启用process.send()和process.on('message')。

var child = spawn('cat', ['index.js', {stdio: 'ipc'});

2 /关于EPIPE

  

EPIPE意味着你正在写另一端的管道或插座   终止了连接。

这就是说,我发现你的观察结果是可疑的,因为如果你不打开管道,stdout&amp;&amp; stderr&amp;&amp;孩子的stdin对象不会被填充。因此,它通常会出现TypeError: Cannot read property 'on' of null等错误。

然后我仔细检查文档并看到fork很特别,我注意到他们没有提供任何stdio选项。但是,据说它启用了send方法。 我的理解是fork方法不会打开任何管道,只有send方法,on('message')机制可用。

此代码有效,console.js保持不变

// master.js
var cp=require("child_process");

var np = cp.fork("./console.js");

np.on("close", function () {
    console.log("child process exit");
});


np.send({Hello:"world"});
np.on("message",function(msg){
    console.log("parent process got a msg:",msg);
});

要做类似的事情,但是使用spawn,我们应该利用stdin来编写,stdout或stderr来监听,

// master.js
var cp=require("child_process");

var np = cp.spawn(process.argv[0], ["./console.js"], {stdio: 'pipe'});

np.stdout.on("data",function(data){
   console.log("child process output:"+data);
});

np.stderr.on("data", function(err){
    console.log("child process output error:"+err);
});

np.on("close", function () {
    console.log("child process exit");
});

np.stdin.end(JSON.stringify({Hello:"world"}))

console.js

#!/usr/bin/env node

var aa=1;
console.log("The aa is :"+aa);


process.stdin.on("data", function (m) {
    console.log("child process got message:", m.toString());
});

process.stdout.write(JSON.stringify({foo:"bar"}))
// process.send({foo:"bar"});

就是这样。我无法就您提供的具体错误给出准确答案。

我希望这会有所帮助。