Node.js 基于事件驱动,通过 child_process 模块创建子进程以利用多核 CPU。本文详解 exec、spawn 和 fork 三种方法的区别、参数及代码实例,涵盖缓冲区处理、流操作及进程间通信机制,帮助开发者选择合适的多进程方案。
前言
Node.js 采用单线程运行模式,但依靠事件驱动机制处理并发请求。这种架构允许在多核 CPU 系统中创建多个子进程,从而有效提升系统整体性能。
每个子进程默认包含三个流对象:child.stdin、child.stdout 和 child.stderr。这些流可以选择与父进程的 stdio 共享,也可以配置为独立的流对象进行数据导出。
Node.js 提供了 child_process 模块用于创建子进程,主要包含以下三种方法:
- exec:通过 child_process.exec 执行命令,该方法会缓存子进程的输出,并通过回调函数将结果返回。
- spawn:通过 child_process.spawn 根据指定的命令行参数创建新进程。
- fork:fork 是 spawn 的特殊形式,专门用于在子进程中运行模块文件,例如 fork('./son.js') 等价于 spawn('node', ['./son.js'])。与 spawn 不同,fork 会在父进程与子进程之间建立通信管道,实现进程间通信。
方法说明
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() 方法
child_process.spawn 用于根据指定的命令行参数创建新进程,语法格式如下:
child_process.spawn(command[, args][, options])参数
参数说明如下:
- command:将要运行的命令。
- args:Array 类型,表示字符串参数数组。
- options Object
- cwd:String 类型,指定子进程的当前工作目录。
- env:Object 类型,用于设置环境变量键值对。
- stdio:Array|String 类型,配置子进程的 stdio。
- detached:Boolean 类型,表示该子进程是否会变成进程组的领导。
- uid:Number 类型,用于设置用户进程的 ID。
- gid:Number 类型,用于设置进程组的 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 执行。
子进程已退出,退出码 0fork 方法
child_process.fork 是 spawn() 方法的特殊形式,用于创建进程,语法格式如下:
child_process.fork(modulePath[, args][, options])参数
参数说明如下:
- modulePath:String 类型,表示将在子进程中运行的模块路径。
- args:Array 类型,表示字符串参数数组。
- options:Object
- cwd:String 类型,指定子进程的当前工作目录。
- env:Object 类型,用于设置环境变量键值对。
- execPath:String 类型,指定创建子进程的可执行文件路径。
- execArgv:Array 类型,表示子进程的可执行文件的字符串参数数组,默认为 process.execArgv。
- silent:Boolean 类型,如果为 true,子进程的 stdin、stdout 和 stderr 将关联至父进程;否则,它们将从父进程中继承。默认为 false。
- uid:Number 类型,用于设置用户进程的 ID。
- gid:Number 类型,用于设置进程组的 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 多进程的方法内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!