跳到主要内容

Node.js 创建子进程的几种方式

在 Node.js 中,我们可以通过 child_process 模块来创建子进程。该模块提供了几种不同的方法,每种方法都有其优缺点和适用场景。下面我将详细介绍几种常用的创建子进程的方法。

child_process.fork()

child_process.fork() 方法允许我们直接从主进程创建一个新的 Node.js 子进程,并运行一个独立的 JavaScript 模块。它会自动建立一个与父进程之间的通信通道,使得父子进程之间可以通过消息传递进行通信。

优点

  1. 可以在一个独立的 Node.js 环境中运行模块,与主进程完全隔离。
  2. 自动建立与父进程之间的通信通道,方便进程间通信。

缺点

  1. 仅限于执行 Node.js 代码,不适用于执行系统命令。

使用场景

  1. 需要在一个独立的 Node.js 环境中运行某个模块时。
  2. 需要一个与主进程完全隔离的环境时。

示例

const { fork } = require('child_process');

const child = fork('child.js');

child.on('message', (msg) => {
console.log('Received message from child:', msg);
});

child.send({ hello: 'from parent' });

child_process.spawn()

child_process.spawn() 方法用于启动一个新的系统进程,适合需要长时间运行的任务,可以持续地收到数据。

优点

  1. 可以执行任意的系统命令。
  2. 适合需要长时间运行并持续输出数据的任务。

缺点

  1. 获取输出结果不如 execexecFile 方便,需要手动处理输出流。

使用场景

  1. 需要与系统命令进行交互时。
  2. 需要处理大量数据输出的场景。

示例

const { spawn } = require('child_process');

const child = spawn('ls', ['-lh', '/usr']);

child.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});

child.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});

child_process.exec()

child_process.exec() 方法用于执行一个系统命令并回调输出结果,适合不产生大量输出的命令。

优点

  1. 可以方便地获取命令的输出结果。
  2. 适合执行输出数据量较小的命令。

缺点

  1. 因为它会缓存所有输出,所以不适合输出大量数据的命令。

使用场景

  1. 需要执行一些简单的系统命令并获取输出结果时。

示例

const { exec } = require('child_process');

exec('ls -lh /usr', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});

child_process.execFile()

child_process.execFile() 方法用于直接执行一个文件而不是一个命令,相比 exec 有更好的性能。

优点

  1. 直接执行一个可执行文件,性能优于 exec

缺点

  1. exec 类似,但不会产生 shell。

使用场景

  1. 需要执行一个可执行文件而不是一个命令时。

示例

const { execFile } = require('child_process');

execFile('/usr/bin/node', ['--version'], (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});