Node.js multi-process


We all know that Node.js runs in single-threaded mode, but it uses event-driven to handle concurrency, which helps us create multiple child processes on multi-core CPU systems, thereby improving performance.

Each child process always has three stream objects: child.stdin, child.stdout and child.stderr. They may share the parent process's stdio stream, or they may be independent redirected stream objects.

Node provides the child_process module to create a child process. The methods are:

  • exec - child_process.exec uses the child process to execute commands and cache the child process. The output of the process and returns the output of the child process in the form of callback function parameters.

  • spawn - child_process.spawn creates a new process using the specified command line arguments.

  • fork - child_process.fork is a special form of spawn(), used for modules running in child processes, such as fork('./son.js ') is equivalent to spawn('node', ['./son.js']) . Different from the spawn method, fork will establish a communication channel between the parent process and the child process for communication between processes.


exec() method

child_process.exec uses the child process to execute the command, caches the output of the child process, and uses the output of the child process as a callback function parameter return in the form.

The syntax is as follows:

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

Parameters

The parameter description is as follows:

command: String, the command to be run , parameters are separated by spaces

options: object, can be:

  • cwd, string, the current working directory of the child process

  • env, object environment variable key-value pair

  • encoding, string, character encoding (default: 'utf8')

  • shell, string, the Shell that will execute the command (default: /bin/sh in UNIX, cmd.exe in Windows, Shell should Recognizes the -c switch in UNIX, or /s /c in Windows. In Windows, command line parsing should be compatible with cmd.exe)##.

  • #timeout, number, timeout (default: 0)

  • maxBuffer, number, the maximum buffer allowed to exist in stdout or stderr (binary) , if exceeded, the child process will be killed (default: 200*1024)

  • killSignal, string, end signal (default: 'SIGTERM')

  • uid, number, set the ID of the user process

  • gid, number, set the ID of the process group

callback: Callback function, including three parameters error, stdout and stderr.

The exec() method returns the largest buffer, waits for the process to end, and returns the contents of the buffer at once.

Example

Let us create two js files support.js and master.js.

support.js file code:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js file code:

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

Execute the above code, the output result is:

$ node master.js 
子进程已退出,退出码 0
stdout: 进程 1 执行。

stderr: 
子进程已退出,退出码 0
stdout: 进程 0 执行。

stderr: 
子进程已退出,退出码 0
stdout: 进程 2 执行。

stderr:

spawn() method

child_process.spawn uses the specified command line parameters to create a new process. The syntax format is as follows:

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

Parameters

Parameter description As follows:

command: The command to be run

args: Array string parameter array

options Object

  • cwd String The current working directory of the child process

  • env Object Environment variable key-value pair

  • stdio Array|String stdio configuration of the child process

  • detached Boolean This child process will become the leader of the process group

  • uid Number Set the ID of the user process

  • gid Number Set the ID of the process group

spawn() method returns stream (stdout & stderr), Used when the process returns large amounts of data. spawn() starts receiving responses as soon as the process starts executing.

Example

Let us create two js files support.js and master.js.

support.js file code:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js file code:

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

Execute the above code, the output result is:

$ node master.js stdout: 进程 0 执行。

子进程已退出,退出码 0
stdout: 进程 1 执行。

子进程已退出,退出码 0
stdout: 进程 2 执行。

子进程已退出,退出码 0

The fork method

child_process.fork is a special form of the spawn() method, used to create a process. The syntax format is as follows:

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

Parameters

The parameter description is as follows:

modulePath: String, the module to be run in the child process

args: Array string parameter array

options : Object

  • cwd String The current working directory of the child process

  • env Object Environment variable key-value pair

  • execPath String Create the executable file of the child process

  • execArgv Array The string parameter array of the executable file of the child process (default: process.execArgv)

  • silent Boolean If true, the stdin, stdout and stderr of the child process will be are associated with the parent process, otherwise they will be inherited from the parent process. (Default: false)

  • uid Number Set the ID of the user process

  • gid Number Set the ID of the process group

In addition to having all the methods of the ChildProcess instance, the returned object also has a built-in communication channel.

h3>Example

Let us create two js files support.js and master.js.

support.js file code:

console.log("进程 " + process.argv[2] + " 执行。" );

master.js file code:

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

Execute the above code, the output result is:

$ node master.js 
进程 0 执行。
子进程已退出,退出码 0
进程 1 执行。
子进程已退出,退出码 0
进程 2 执行。
子进程已退出,退出码 0