Node .js multiple processes
The Node .js itself runs in a single-threaded mode, but it uses event-driven processing to handle sympation, which helps us create multiple sub-processes on multi-core cpu systems, improving performance.
Each child process always comes with three flow objects: child.stdin, child.stdout, and child.stderr. They may share the stdio flow of the parent process, or they may be separate flow objects that are directed.
Node provides child_process modules to create sub-processes by:
-
exec - child_process.exec uses sub-processes to execute commands, cache the output of sub-processes, and return the output of sub-processes as callback function parameters.
-
spawn - child_process.spawn creates a new process using the specified command line parameters.
-
fork - child_process.fork is a special form of spawn() for modules that run in sub-processes, such as fork ('./son.js') equivalent to spawn ('node', './son.js'). Unlike the spawn method, fork establishes a communication pipeline between the parent and child processes for communication between processes.
exec() method
child_process.exec uses sub-processes to execute commands, cache the output of sub-processes, and return the output of sub-processes as callback function parameters.
The syntax looks like this:
child_process.exec(command[, options], callback)
Parameters
The parameters are described below:
command: String, command to run, argument separated by spaces
Options: Objects, which 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, the string, will execute the command shell
/bin/sh
in UNIX,cmd.exe
in Windows, shell should be able-c
in UNIX, or/s /c
in Windows. In Windows, command-line resolution should becmd.exe
- timeout, number, timeout (default: 0)
- maxBuffer, number, maximum buffer (binary) allowed in stdout or stderr, if exceeded then the sub-process will be killed (default: 200 x 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, which contains three parameters error, stdout, and stderr.
The exec() method returns the largest buffer and waits for the process to end, returning the contents of the buffer at once.
Instance
Let's create two js files superport .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); }); }
The above code is executed and the output is:
$ node master.js 子进程已退出,退出码 0 stdout: 进程 1 执行。 stderr: 子进程已退出,退出码 0 stdout: 进程 0 执行。 stderr: 子进程已退出,退出码 0 stdout: 进程 2 执行。 stderr:
Spawn() method
child_process.spawn creates a new process using the specified command line parameters, in the following syntax format:
child_process.spawn(command[, args][, options])
Parameters
The parameters are described below:
command: The command that will be run
args: Array string argument array
options Object
- cwd:String, the current working directory of the child process
- env:Object, environment variable key value pair
- stdio:Array| String, the stdio configuration of the child process
- Detached: Boolean, this sub-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
The spawn() method returns a stream (stdout and stderr), which is used when a process returns a large amount of data. The process starts receiving responses when it starts executing spawn().
Instance
In this example we create two js files superport.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); }); }
The above code is executed and the output 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 for creating processes in the following syntax format:
child_process.fork(modulePath[, args][, options])
Parameters
The parameters are described below:
ModulePath : String, the module that will run in the sub-process
Args : Array, array of string parameters
options :Object
- cwd:String, the current working directory of the child process
- env:Object, environment variable key value pair
- ExecPath:String, create an executable file for the child process
- execArgv:Array, array of string parameters for executable files of sub-processes (default: process.execArgv)
-
Silent: Boolean, if
true
stdin
stdout
andstderr
the child process will be associated with the parent process, otherwise they will inherit from the parent process. (The default is:false
- uid:Number, set the ID of the user process
- gid:Number, set the ID of the process group
The returned object has a built-in communication channel in addition to all methods that have ChildProcess instances.
Instance
Let's create two js files superport .js and master .js.
The support .js file code looks like this:
console.log("进程 " + process.argv[2] + " 执行。" );
The master .js file code looks like this:
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); }); }
The above code is executed and the output is:
$ node master.js 进程 0 执行。 子进程已退出,退出码 0 进程 1 执行。 子进程已退出,退出码 0 进程 2 执行。 子进程已退出,退出码 0