Node.js 多进程详解:exec、spawn 与 fork 方法对比

作者:后端茶话

时间:2026-10-23

浏览:424

Node.js 基于单线程事件驱动模型,利用 child_process 模块可在多核 CPU 上创建子进程以提升性能。本文详细解析 exec、spawn 和 fork 三种子进程创建方法,涵盖其语法结构、参数配置及适用场景,并通过代码实例展示如何缓存输出、处理流数据及建立进程间通信。

文章目录

Node.js 多进程基础

Node.js 默认采用单线程运行模式,但通过事件驱动机制处理并发请求。这种架构允许在多核 CPU 系统中创建多个子进程,从而充分利用硬件资源并提升整体性能。

每个子进程默认包含三个流对象:child.stdin、child.stdout 和 child.stderr。这些流可以选择与父进程的 stdio 共享,也可以配置为独立的被导流对象。

子进程创建方法概述

Node.js 提供了 child_process 模块用于创建子进程,主要包含以下三种方法:

  • exec 方法:通过子进程执行命令,会缓存输出结果,并通过回调函数将子进程的输出返回。
  • spawn 方法:使用指定的命令行参数创建新进程,适用于需要持续接收大量数据的场景。
  • fork 方法:这是 spawn() 的特殊形式,专门用于在子进程中运行模块(例如 fork('./son.js') 等价于 spawn('node', ['./son.js']))。与 spawn 不同,fork 会在父进程与子进程之间建立通信管道,实现进程间通信。

exec 方法详解与实例

exec() 方法详解

child_process.exec 用于执行命令,它会缓存子进程的输出,并通过回调函数参数将结果返回。

其语法格式如下:

child_process.exec(command[, options], callback)

参数说明

具体参数定义如下:

command:字符串类型,表示要执行的命令,多个参数之间使用空格分隔。

options:对象类型,可包含以下配置项:

  • cwd:字符串,指定子进程的当前工作目录。
  • env:对象,用于设置环境变量键值对。
  • encoding:字符串,指定字符编码,默认为 'utf8'。
  • shell:字符串,指定执行命令的 Shell。在 UNIX 系统中默认为 /bin/sh,在 Windows 中默认为 cmd.exe。Shell 需能识别 UNIX 中的 -c 开关,或 Windows 中的 /s /c 开关。Windows 下的命令行解析应兼容 cmd.exe。
  • timeout:数字,指定超时时间,默认为 0(无超时限制)。
  • maxBuffer:数字,指定 stdout 或 stderr 中允许存在的最大缓冲区大小(二进制)。若超出此限制,子进程将被杀死,默认为 200*1024。
  • killSignal:字符串,指定终止信号,默认为 'SIGTERM'。
  • uid:数字,用于设置进程的用户 ID。
  • gid:数字,用于设置进程组的 ID。

callback:回调函数,包含三个参数:error、stdout 和 stderr。

exec() 方法会返回最大的缓冲区,并等待进程结束,一次性返回缓冲区的内容。

实例演示

我们需要创建两个 JS 文件:support.js 和 master.js。

support.js 文件代码如下:


console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码如下:


const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
  var workerProcess = child_process.exec('node support.js '+i, function (error, stdout, stderr) {
    if (error) {
      console.log(error.stack);
      console.log('Error code: '+error.code);
      console.log('Signal received: '+error.signal);
    }
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
  });
 
  workerProcess.on('exit', function (code) {
    console.log('子进程已退出,退出码 '+code);
  });
}

执行上述代码,输出结果如下:

$ node master.js 子进程已退出,退出码 0 stdout: 进程 1 执行。

stderr: 子进程已退出,退出码 0 stdout: 进程 0 执行。

stderr: 子进程已退出,退出码 0 stdout: 进程 2 执行。

stderr:

spawn 方法详解与实例

spawn() 方法详解

child_process.spawn 用于使用指定的命令行参数创建新进程,语法格式如下:

child_process.spawn(command[, args][, options])

参数说明

具体参数定义如下:

command:字符串,表示要执行的命令。

args:数组类型,包含字符串形式的参数数组。

options:对象类型,可包含以下配置:

  • cwd:字符串,指定子进程的当前工作目录。
  • env:对象,用于设置环境变量键值对。
  • stdio:数组或字符串,配置子进程的 stdio。
  • detached:布尔值,若为 true,该子进程将成为进程组的领导。
  • uid:数字,用于设置进程的用户 ID。
  • gid:数字,用于设置进程组的 ID。

spawn() 方法返回流(stdout 和 stderr),适用于进程返回大量数据的场景。一旦进程开始执行,spawn() 便开始接收响应。

实例演示

我们需要创建两个 JS 文件:support.js 和 master.js。

support.js 文件代码如下:


console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码如下:


const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
  var workerProcess = child_process.spawn('node', ['support.js', i]);
 
  workerProcess.stdout.on('data', function (data) {
   console.log('stdout: ' + data);
  });
 
  workerProcess.stderr.on('data', function (data) {
   console.log('stderr: ' + data);
  });
 
  workerProcess.on('close', function (code) {
   console.log('子进程已退出,退出码 '+code);
  });
}

执行上述代码,输出结果如下:

$ node master.js stdout: 进程 0 执行。

子进程已退出,退出码 0 stdout: 进程 1 执行。

子进程已退出,退出码 0 stdout: 进程 2 执行。

子进程已退出,退出码 0

fork 方法详解与实例

fork 方法详解

child_process.fork 是 spawn() 方法的特殊形式,用于创建进程,语法格式如下:

child_process.fork(modulePath[, args][, options])

参数说明

具体参数定义如下:

modulePath:字符串,指定要在子进程中运行的模块路径。

args:数组类型,包含字符串形式的参数数组。

options:对象类型,可包含以下配置:

  • cwd:字符串,指定子进程的当前工作目录。
  • env:对象,用于设置环境变量键值对。
  • execPath:字符串,指定创建子进程的可执行文件路径。
  • execArgv:数组,指定子进程可执行文件的字符串参数数组,默认为 process.execArgv。
  • silent:布尔值,若为 true,子进程的 stdin、stdout 和 stderr 将关联至父进程;否则,它们将从父进程中继承(默认为 false)。
  • uid:数字,用于设置进程的用户 ID。
  • gid:数字,用于设置进程组的 ID。

返回的对象除了拥有 ChildProcess 实例的所有方法外,还包含一个内置的通信信道。

实例演示

我们需要创建两个 JS 文件:support.js 和 master.js。

support.js 文件代码如下:


console.log("进程 " + process.argv[2] + " 执行。" );

master.js 文件代码如下:


const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
  var worker_process = child_process.fork("support.js", [i]);  
 
  worker_process.on('close', function (code) {
   console.log('子进程已退出,退出码 ' + code);
  });
}

执行上述代码,输出结果如下:

$ node master.js 进程 0 执行。 子进程已退出,退出码 0 进程 1 执行。 子进程已退出,退出码 0 进程 2 执行。 子进程已退出,退出码 0

以上就是详细分析 Node.js 多进程的全部内容,更多关于 Node.js 多进程的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章