深入理解NodeJS 多进程和集群

2020-06-17 07:02:20易采站长站整理

// 文件:~test/sub_process_1.js
// 获取 --port 和 3000
process.argv.slice(2).forEach(item => process.stdout.write(item));


// 文件:~test/sub_process_2.js
const fs = require("fs");

// 读取主进程传递的参数并写入文件
process.stdout.on("data", data => {
fs.writeFile("param.txt", data, () => {
process.exit();
});
});

有一点需要注意,在子进程 2 写入文件的时候,由于主进程不知道子进程 2 什么时候写完,所以主进程会卡住,需要子进程在写入完成后调用 process.exit 方法退出子进程,子进程退出并关闭后,主进程会随之关闭。

在我们给 options 配置 stdio 时,数组内其实可以对标准输入、标准输出和错误输出分开配置,默认数组内为 pipe 时代表三者都为 pipe,分别配置看下面案例。


// 文件:process.js
const { spawn } = require("spawn");
const path = require("path");

// 创建子进程
let child = spawn("node", ["sub_process.js"], {
cwd: path.join(__dirname, "test"),
stdio: [0, "pipe", 2]});

// world


// 文件:~test/sub_process.js
console.log("hello");
console.error("world");

上面代码中对 stderr 实现了默认打印而不通信,对标准输入实现了通信,还有一种情况,如果希望子进程只是默默的执行任务,而在主进程命令窗口什么类型的输出都禁止,可以在数组中对应位置给定值 ignore,将上面案例修改如下。


// 文件:process.js
const { spawn } = require("spawn");
const path = require("path");

// 创建子进程
let child = spawn("node", ["sub_process.js"], {
cwd: path.join(__dirname, "test"),
stdio: [0, "pipe", "ignore"]});


// 文件:~test/sub_process.js
console.log("hello");
console.error("world");

这次我们发现无论标准输出和错误输出都没有生效,上面这些方式其实是不太方便的,因为输出有 stdout 和 stderr,在写法上没办法统一,可以通过下面的方式来统一。

3、标准进程通信


// 文件:process.js
const { spawn } = require("spawn");
const path = require("path");

// 创建子进程
let child = spawn("node", ["sub_process.js"], {
cwd: path.join(__dirname, "test"),
stdio: [0, "pipe", "ignore", "ipc"]});

child.on("message", data => {
console.log(data);

// 回复消息给子进程
child.send("world");

// 杀死子进程
// process.kill(child.pid);
});

// hello