📜  Node.js 子进程

📅  最后修改于: 2022-05-13 01:56:54.775000             🧑  作者: Mango

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);
});

输出: