Node.js 子进程
Node.js 是一个 Web 开发框架,它提供了各种可以使用的模块。通常,Node.js 允许单线程、非阻塞性能,但在 CPU 中运行单线程无法处理不断增加的工作负载,因此 child_process 模块可用于生成子进程。子进程使用内置的消息传递系统相互通信。
以下是在 Node.js 中创建子进程的四种不同方式:
- spawn() 方法
- fork() 方法
- exec() 方法
- execFile() 方法
上述方式解释如下:
spawn() 方法:此方法使用给定的命令和 args 中的命令行参数生成一个新进程。 ChildProcess 实例实现了 EventEmitterAPI,它使我们能够直接为子对象上的事件注册处理程序。可以注册以使用 ChildProcess 处理的一些事件是退出、断开连接、错误、关闭和消息。
句法:
child_process.spawn(command[, args][, options])
参数:
- command:接受一个字符串,它是要运行的命令。
- args:字符串参数列表。默认值为空数组。
- 选项:
- shell:接受一个布尔值。如果为 true,则在 shell 内运行命令。可以将不同的 shell 指定为字符串。默认值为 false,这意味着没有外壳。默认情况下, spawn() 不会创建 shell 来执行命令,因此在调用子进程时将其作为选项传递很重要。
可以根据需要使用其他选项,例如 cwd、env、argv0、stdio 等。
返回值:返回一个 ChildProcess 对象。
例子:
const { spawn } = require('child_process');
const child = spawn('dir', ['D:\Test'], {shell: true});
child.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
child.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
child.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
输出:
fork() 方法: child_process.fork() 是 child_process.spawn() 的一个特例,父进程和子进程可以通过 send() 相互通信。 fork() 允许从主事件循环中分离计算密集型任务。子进程独立于父进程,除了它们之间建立的 IPC 通信通道。每个进程都有自己的内存,因此调用大量子进程会影响应用程序的性能。 child_process.fork() 不支持 shell 选项。
句法:
child_process.fork(modulePath[, args][, options])
参数:
- modulePath:接受一个字符串,该字符串指定要在子进程中运行的模块。
- args:字符串参数列表。
- 选项: cwd、detached、env、execPath、execArgv 是此方法的一些可用选项。
返回值:返回一个 ChildProcess 实例。
示例:文件名:fork.js
// Write Javascript code here
var cp = require('child_process');
var child = cp.fork(__dirname + '/sub.js');
child.on('message', function(m) {
console.log('Parent process received:', m);
});
child.send({ hello: 'from parent process' });
child.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
文件名:sub.js
process.on('message', function(m) {
console.log('Child process received:', m);
});
process.send({ hello: 'from child process' });
输出:
exec() 方法:该方法首先创建一个shell,然后执行命令。
句法:
child_process.exec(command[, options][, callback])
参数:
- command:接受一个字符串,该字符串指定要使用空格分隔的参数运行的命令。
- 选项:一些可用的选项是 cwd、env、编码、shell、超时等
- callback:进程终止时调用的回调函数。该函数的参数分别是 error、stdout 和 stderr。
返回值:返回 ChildProcess 的一个实例。
例子:
const { exec } = require('child_process');
// Counts the number of directory in
// current working directory
exec('dir | find /c /v ""', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: No. of directories = ${stdout}`);
if (stderr!= "")
console.error(`stderr: ${stderr}`);
});
输出:
execFile() 方法: child_process.execFile()函数默认不生成 shell。它比 child_process.exec() 稍微高效一些,因为指定的可执行文件直接作为新进程生成。
句法:
child_process.execFile(file[, args][, options][, callback])
参数:
- file:接受一个字符串,该字符串指定要运行的文件的名称或路径。
- args:字符串参数列表。
- 选项:一些可用的选项是 cwd、env、编码、shell、超时等
- callback:进程终止时调用的回调函数。该函数的参数分别是 error、stdout 和 stderr。
返回值:返回 ChildProcess 的一个实例。
例子:
const { execFile } = require('child_process');
// Executes the exec.js file
const child = execFile('node', ['exec.js'],
(error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
输出: