Node.js - 扩展应用程序


Node.js 以单线程模式运行,但它使用事件驱动范例来处理并发。它还有助于创建子进程,以利用基于多核 CPU 的系统上的并行处理。

子进程始终具有三个流child.stdinchild.stdoutchild.stderr,它们可以与父进程的 stdio 流共享。

Node提供了child_process模块​​,主要有以下三种创建子进程的方式。

  • exec - child_process.exec 方法在 shell/控制台中运行命令并缓冲输出。

  • spawn - child_process.spawn 使用给定命令启动一个新进程。

  • fork - child_process.fork 方法是 spawn() 的一个特殊情况,用于创建子进程。

exec() 方法

child_process.exec 方法在 shell 中运行命令并缓冲输出。它具有以下签名 -

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

参数

这是所使用参数的描述 -

  • command(字符串)要运行的命令,带有空格分隔的参数

  • options(对象)可以包含以下一个或多个选项 -

    • cwd (String) 子进程的当前工作目录

    • env (Object) 环境键值对

    • 编码(字符串)(默认:'utf8')

    • shell(字符串)执行命令的 Shell(默认值:UNIX 上为“/bin/sh”,Windows 上为“cmd.exe”,shell 应该理解 UNIX 上的 -c 开关或 Windows 上的 /s /c。在 Windows 上,命令行解析应该兼容cmd.exe。)

    • 超时(数量)(默认值:0)

    • maxBuffer(数量)(默认:200*1024)

    • KillSignal(字符串)(默认值:'SIGTERM')

    • uid(数字) 设置进程的用户身份。

    • gid(数字) 设置进程的组标识。

  • 函数获取三个参数errorstdoutstderr,当进程终止时,将使用输出调用这些参数。

exec() 方法返回一个具有最大大小的缓冲区,并等待进程结束并尝试立即返回所有缓冲的数据。

例子

让我们创建两个名为 support.js 和 master.js 的 js 文件 -

文件:support.js

console.log("Child Process " + process.argv[2] + " executed." );

文件: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('Child process exited with exit code '+code);
   });
}

现在运行 master.js 来查看结果 -

$ node master.js

验证输出。服务器已启动。

Child process exited with exit code 0
stdout: Child Process 1 executed.

stderr:
Child process exited with exit code 0
stdout: Child Process 0 executed.

stderr:
Child process exited with exit code 0
stdout: Child Process 2 executed.

spawn() 方法

child_process.spawn 方法使用给定的命令启动一个新进程。它具有以下签名 -

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

参数

这是所使用参数的描述 -

  • 命令(字符串)要运行的命令

  • args (Array) 字符串参数列表

  • options(对象)可以包含以下一个或多个选项 -

    • cwd(字符串)子进程的当前工作目录。

    • env(对象)环境键值对。

    • stdio(数组)字符串子级的 stdio 配置。

    • customFds(数组) 已弃用 子级用于 stdio 的文件描述符。

    • detached (布尔值) 子进程将成为进程组的领导者。

    • uid(数字) 设置进程的用户身份。

    • gid(数字) 设置进程的组标识。

spawn() 方法返回流(stdout 和 stderr),当进程返回大量数据时应该使用它。进程开始执行后,spawn() 就开始接收响应。

例子

创建两个名为 support.js 和 master.js 的 js 文件 -

文件:support.js

console.log("Child Process " + process.argv[2] + " executed." );

文件: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('child process exited with code ' + code);
   });
}

现在运行 master.js 来查看结果 -

$ node master.js

验证输出。服务器已启动

stdout: Child Process 0 executed.

child process exited with code 0
stdout: Child Process 1 executed.

stdout: Child Process 2 executed.

child process exited with code 0
child process exited with code 0

fork() 方法

child_process.fork方法是spawn()的一个特例,用于创建Node进程。它具有以下签名 -

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

参数

这是所使用参数的描述 -

  • modulePath(字符串)要在子级中运行的模块。

  • args (Array) 字符串参数列表

  • options(对象)可以包含以下一个或多个选项 -

    • cwd(字符串)子进程的当前工作目录。

    • env(对象)环境键值对。

    • execPath (String) 用于创建子进程的可执行文件。

    • execArgv(数组)传递给可执行文件的字符串参数列表(默认值:process.execArgv)。

    • silent (Boolean) 如果为 true,则子级的 stdin、stdout 和 stderr 将通过管道传输到父级,否则将从父级继承,请参阅spawn() 的 stdio 的“pipe”和“inherit”选项更多详细信息(默认为 false)。

    • uid(数字) 设置进程的用户身份。

    • gid(数字) 设置进程的组标识。

除了具有普通 ChildProcess 实例中的所有方法之外,fork 方法还返回一个具有内置通信通道的对象。

例子

创建两个名为 support.js 和 master.js 的 js 文件 -

文件:support.js

console.log("Child Process " + process.argv[2] + " executed." );

文件: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('child process exited with code ' + code);
   });
}

现在运行 master.js 来查看结果 -

$ node master.js

验证输出。服务器已启动。

Child Process 0 executed.
Child Process 1 executed.
Child Process 2 executed.
child process exited with code 0
child process exited with code 0
child process exited with code 0