feng xiaohan

child_process

Nodejs 核心 API,可用于处理 cpu 密集型应用

api

  • exec异步方法。一般会有一个回调函数,返回 buffer。

    可用于执行 shell 命令,或跟软件进行交互

  • execSync同步的方法

exec/execSync

执行指定命令

exec('node-v', (err, stdout, stderr) => {
  if (err){
    retunr err
  }
})

execSync('mkdir test') // 执行命令
execSync('start chrome http://www.baidu.com') // 软件交互
  • 适用于执行较小的 shell 命令;
  • 想要立即拿到结果的 shell 可以用 execSync;
  • 字节上限 200kb,超出则报错

spawn/spawnSync

执行指定命令

const netInfo = execSync("netstat");
console.log(netInfo); // 卡住,数量太大

const { stdout } = spawn("netstat", ["-a"]);
stdout.on("data", (msg) => {
  console.log(msg.toString());
});
stdout.on("close", (msg) => {
  console.log("end");
});
  • 没有字节上限,返回的是流
  • 实时返回
  • 有结束事件

_更多配置项_:

const { stdout } = spawn("netstat", ["-a"], {
  cwd: "", // string 子进程的当前工作目录
  env: "", // object 环境变量键值对
  encodingL: "", // string 默认为'utf8'.
  shell: "", // string 用于执行命令的 she11, 在 UNIX 上默认为'/bin/sh',在 windows 上默认为 process.env.ComSpec。
  timeout: "", // 超时时间,默认为 0
  maxBuffer: "", //stdout 或 stderr 允许的最大字节数。默认为 288*1024.。如果超过限制,则子进程会被终止
  killSignal: "", // string|integer 默认为'SIGTERM'
  uid: "", // 设置该进程的用户标识。
  gid: "", // 设置该进程的组标识。
});

execFile/execFileSync

执行可执行文件

bat.sh(mac、linux)

bat.cmd(windows)

// bat.cmd
echo 'start'
mkdir test
cd ./test
echo console.log('test bar') >test.js
echo 'end'
execFile(path.resolve(__dirname, "./bat.cmd"), null, (err, stdout) => {});

底层实现顺序

exec -> execFile -> spawn

fork

只接受 js 模块,为 js 创建子进程

注意:web worker 是浏览器的,而 fork 是 node 的。

const childProcess = fork("./child.js");
childProcess.sent("hello,我是主进程");

// child.js
process.on("message", (msg) => {
  console.log("收到消息了", msg);
});

原理:底层通过 IPC 去通讯,IPC 又基于 libuv 实现,libuv 会根据不同的操作系统调用不同的命令实现。(windows:named pipe | posix: unix domain socket)