Child_process抛出错误:写EPIPE

gfa*_*fan 1 javascript child-process node.js

我只是练习一些关于child_process @the 链接的节点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"});
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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);
});
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误:

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

TypeError: np.send is not a function
Run Code Online (Sandbox Code Playgroud)

我再次访问节点js官方文档,我没有发现spawn()和fork()是非常不同的.所以我想知道为什么np.send不是函数?

官方文件没有提到一些问题吗?

mh-*_*bon 5

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

当子项被分叉或者管道设置为IPC时,child_process.send方法可用

叉子

使用child_process.fork()时,您可以使用child.send(message [,sendHandle] [,callback])写入子项,并通过子项上的"message"事件接收消息.

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'});
Run Code Online (Sandbox Code Playgroud)

2 /关于EPIPE

EPIPE表示当另一端终止连接时,您正在写入管道或套接字.

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

然后我仔细检查文档,看到叉非常特殊,我注意到他们没有提供任何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);
});
Run Code Online (Sandbox Code Playgroud)

要做类似的事情,但是使用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"}))
Run Code Online (Sandbox Code Playgroud)

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"});
Run Code Online (Sandbox Code Playgroud)

而已.我无法为您提供有关您提供的具体错误的准确答案.

我希望这有帮助.