我只是练习一些关于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不是函数?
官方文件没有提到一些要点吗?
答案 0 :(得分:5)
1 /关于np.send找不到方法
当子项被分叉或者管道设置为IPC时,child_process.send方法可用
使用child_process.fork()时,您可以使用 child.send(message [,sendHandle] [,callback])和消息是 通过关于孩子的“消息”事件收到。
'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"});
就是这样。我无法就您提供的具体错误给出准确答案。
我希望这会有所帮助。