进程创建
一、认识
Node
提供了 child_process
模块来创建子进程,方法有:
-
Spawning .bat and .cmd files on Windows
: -
child_process.exec(command[, options][, callback])
: 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。child_process.exec
使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。exec()
方法返回最大的缓冲区,并等待进程结束,一次性返回缓冲区的内容。child_process.exec
比较适合开销比较小的任务,因为它是执行完之后才会调用回调把信息打印出来。 -
child_process.execFile(file[, args][, options][, callback])
-
child_process.fork(modulePath[, args][, options])
: 是spawn()
的特殊形式,用于在子进程中运行的模块,如fork('./son.js')
相当于spawn('node', ['./son.js'])
。与spawn
方法不同的是,fork
会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。child_process.fork
是spawn()
方法的特殊形式,用于创建进程。返回的对象除了拥有ChildProcess
实例的所有方法,还有一个内建的通信信道。 -
child_process.spawn(command[, args][, options])
: 使用指定的命令行参数创建新进程。child_process.spawn
使用指定的命令行参数创建新进程。spawn()
方法返回流 (stdout & stderr
),在进程返回大量数据时使用。进程一旦开始执行时spawn()
就开始接收响应。child_process.spawn
适合执行耗时任务, 需要不断打印日志, 因为是通过流的方式输出结果。比如在安装依赖。
通过 child_process
模块,可以实现1
个主进程,多个子进程的模式,主进程称为master
进程,子进程又称为工作进程。
二、创建同步进程
2.1 child_process.execFileSync(file[, args][, options])
2.2 child_process.execSync(command[, options])
2.3 child_process.spawnSync(command[, args][, options])
三、创建异步进程
3.1 Spawning .bat and .cmd files on Windows
3.2 child_process.exec(command[, options][, callback])
child_process.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 应当能识别 -c开关在 UNIX 中,或 /s /c 在 Windows 中。 在Windows 中,命令行解析应当能兼容cmd.exe) -
timeout
: 数字,超时时间(默认: 0) -
maxBuffer
: 数字, 在 stdout 或 stderr 中允许存在的最大缓冲(二进制),如果超出那么子进程将会被杀死 (默认: 200*1024) -
killSignal
: 字符串,结束信号(默认:'SIGTERM') -
uid
: 数字,设置用户进程的 ID -
gid
: 数字,设置进程组的 ID
-
-
callback
: 回调函数,包含三个参数error
,stdout
和stderr
。
用法
master.js
const path = require("path");
const { exec } = require("child_process");
const workerProcess01 = exec(`node ${path.resolve(__dirname, "support.js")} 01`, 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);
});
workerProcess01.on("exit", function(code){
console.log("子进程已退出,退出码 " + code);
});
const workerProcess02 = exec(`node ${path.resolve(__dirname, "support.js")} 02`, 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);
});
workerProcess02.on("exit", function(code){
console.log("子进程已退出,退出码 " + code);
});
support.js
console.log("进程" + process.argv[2] + "执行完毕")
3.3 child_process.execFile(file[, args][, options][, callback])
3.4 child_process.fork(modulePath[, args][, options])
child_process.fork
是 spawn()
方法的特殊形式,用于创建进程。返回的对象除了拥有 ChildProcess
实例的所有方法,还有一个内建的通信信道。
语法
child_process.fork(modulePath[, args][, options])
-
modulePath
:String
,将要在子进程中运行的模块 -
args
:Array
字符串参数数组 -
options
:-
cwd String
: 子进程的当前工作目录 -
env Object
: 环境变量键值对 -
execPath String
: 创建子进程的可执行文件 -
execArgv Array
: 子进程的可执行文件的字符串参数数组(默认: process.execArgv) -
silent Boolean
: 如果为true
,子进程的stdin
,stdout
和stderr
将会被关联至父进程,否则,它们将会从父进程中继承。(默认为:false) -
uid Number
: 设置用户进程的 ID -
gid Number
: 设置进程组的 ID
-
用法
const path = require("path");
const { fork } = require("child_process");
const workerProcess01 = fork(path.resolve(__dirname, "support.js"), ["01"]);
// 主进程向子进程发送消息
workerProcess01.send("hello support process", () => {
// 发送完消息后,需要关闭两个进程之间的通信,不然进程会一直等待,即光标会一直闪烁
workerProcess01.disconnect();
});
// 主进程接收子进程消息
workerProcess01.on("message", (msg) => {
console.log(msg);
});
workerProcess01.on("close", function (code) {
console.log("子进程已退出,退出码 " + code);
});
const workerProcess02 = fork(path.resolve(__dirname, "support.js"), ["02"]);
workerProcess02.on("close", function (code) {
console.log("子进程已退出,退出码 " + code);
});
3.5 child_process.spawn(command[, args][, options])
child_process.spawn
使用指定的命令行参数创建新进程。spawn()
方法返回流 (stdout & stderr
),在进程返回大量数据时使用。进程一旦开始执行时 spawn()
就开始接收响应。
child_process.spawn
适合执行耗时任务, 需要不断打印日志, 因为是通过流的方式输出结果。比如在安装依赖。
语法
child_process.spawn(command[, args][, options])
-
command
: 将要运行的命令 -
args
:Array
字符串参数数组 -
options
:-
cwd String
: 子进程的当前工作目录 -
env Object
: 环境变量键值对 -
stdio Array|String
: 子进程的stdio
配置 -
detached Boolean
: 这个子进程将会变成进程组的领导 -
uid Number
: 设置用户进程的 ID -
gid Number
: 设置进程组的 ID
-
用法
master.js
const path = require("path");
const { spawn } = require("child_process");
const workerProcess01 = spawn("node", [
path.resolve(__dirname, "support.js"),
"01",
]);
workerProcess01.stdout.on("data", function (data) {
console.log("stdout: " + data);
});
workerProcess01.stderr.on("data", function (data) {
console.log("stderr: " + data);
});
workerProcess01.on("close", function (code) {
console.log("子进程已退出,退出码 " + code);
});
const workerProcess02 = spawn("node", [
path.resolve(__dirname, "support.js"),
"02",
]);
workerProcess02.stdout.on("data", function (data) {
console.log("stdout: " + data);
});
workerProcess02.stderr.on("data", function (data) {
console.log("stderr: " + data);
});
workerProcess02.on("close", function (code) {
console.log("子进程已退出,退出码 " + code);
});
support.js
console.log("进程" + process.argv[2] + "执行完毕")