Objective
node. JS is a single-threaded programming model, and the praise and criticism of node. JS is also due to its single-threaded model, where all tasks are done in one thread (I/O, etc.). The single-threaded model not only makes the code very concise, but also avoids the complexity of thread scheduling, and it is not applicable to CPU-intensive computing applications because of the single thread.
In the kernel of node. js, we are given a new option to create a new process through the Child_process module, which enables multi-core parallel computing.
Directory
- Child_process Introduction
- Basic use of child_process: Spawn, exec, execfile, fork
1. Child_process Introduction
Child_process is a very important module of node. js that enables you to create multiple processes to take advantage of a single, multi-core computing resource. Although Nodejs is inherently single-threaded, with the Child_process module, you can create sub-processes directly in the program and communicate between the master and child processes, and when the child process finishes running, the main process then reads the result of the child process with the callback function.
This article is only introduced from the use of the Child_process module, for in-depth content please refer to the official documentation, https://nodejs.org/api/child_process.html
About the node. JS thread Good article: Https://cnodejs.org/topic/518b679763e9f8a5424406e9
2. Basic use of child_process
The Child_process module, which consists mainly of 4 asynchronous process functions (Spawn,exec,execfile,fork) and 3 synchronization process functions (Spawnsync,execfilesync,execsync), is included in the v0.12.0 version. Spawn in an asynchronous function is the most basic function to create a child process, and the other three async functions are encapsulated in varying degrees to spawn. Spawn can only run specified programs, parameters need to be given in the list, and exec can run complex commands directly.
For example, to run the Du-sh/disk1 command, the Spawn function needs to be written as spawn (' du ', ['-sh ', '/disk1 '), and exec (' du-sh/disk1 ') can be written directly when using the EXEC function. EXEC will parse the shell first, so using the EXEC function makes it easier to use complex shell commands, including pipelines, redirects, and so on. Let's test it for each asynchronous function.
System environment
- Linux Ubuntu 14.04.1 LTS 64bit
- Nodejs:v0.13.0-pre
- npm:1.4.28
Create a project
~ cd/disk1/Demo~ mkdir nodejs-childprocess && CD nodejs-childprocess
2.1 Spawn function
Spawn from a definition, there are 3 parameters.
child_process.spawn(command[, args][, options])
- Command: Commands that execute only
- Args: Parameter list, multiple parameters can be entered
- Options: Environment variable objects
Where the environment variable object consists of 7 properties:
- CWD: The current working directory of the child process
- ENV: Environment variable key value pair
- Stdio: Child process stdio Configuration
- Customfds: File identifier used as a child process stdio
- Detached: Master control of the process group
- UID: The ID of the user process.
- GID: ID of the process group.
First, let's run the command of DU as mentioned above. Directly on the command line, run the result.
~ du-sh/disk1582m /disk1
New File Spawn.js
~ vi spawn.jsvar child = require (' child_process '); var du = Child.spawn (' du ', ['-sh ', '/disk1 '));d U.stdout.on (function (data) { Console.log (' stdout: ' + data '); Du.stderr.on (function (data) { console.log (' stderr: ' + data);}); Du.on (function (code) { Console.log (' child process exited with code ' + code);});
The result of running through node
~ node spawn.jsstdout:582m with code 0
The result of the output is the same, so that we can easily invoke the system command asynchronously, Spawn is not supported by the callback function, the stream to send data to the main process, so as to achieve a multi-process data exchange.
The direct application scenario for this feature is "system monitoring". Under Linux, we have a lot of command-line tools that can monitor the CPU, memory, IO, network and other data in real-time, then using node's child_process module can easily put this data into our own application.
For example, we use the Mpstat command to monitor the usage of the user's CPU. Let's look at the effect of the Mpstat command directly.
~ Mpstat 1Linux3.13.0-32-generic (APE3) 03/20/2015 _x86_64_ (4CPU)11:45:56 AM CPU%usr%nice%sys%iowait%irq%soft%steal%guest%gnice%Idle11:45:57 am All 96.50 0.00 3.50 0.00 0.00 0.00 0.00 0.00 0.00 0.0011:45:58 AM All 96.50 0.00 3.25 0.00 0.25 0.00 0.00 0.00 0.00 0.0011:45:59 AM All 96.50 0.00 3.50 0.00 0.00 0.00 0.00 0.00 0.00 0.0011:46:00 AM All 96.50 0.00 3.50 0.00 0.00 0.00 0.00 0. XX 0.00 0.0011:46:01 AM all 96.26 0.00 3.24 0.00 0.25 0.00 0.25 0.00 0.00 0.0011:46:02 AM All 96.75 0.00 3.25 0.00 0.00 0.00 0.00 0.00 0.00 0.0011:46:03 AM All 96.51 0.00 3.24 0.00 0.25 0.00 0.00 0.00 0.00 0.00^Caverage:all96.50 0.00 3.35 0.00 0.11 0.00 0.04 0.00 0.00 0.00
We create a new file Mpstat.js, read the data from the Mpstat command, and then output only the%USR data.
~VI mpstat.jsvarChild = require (' child_process ');varMpstat = Child.spawn (' Mpstat ', [' 1 ']);//Linux 3.13.0-32-generic (ape3) 03/20/2015 _x86_64_ (4 CPU)//11:27:12 AM CPU%usr%nice%sys%iowait%irq%soft%steal%guest%gnice%idle//11:27:13 AM All 96.50 0.00 3.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00varLine = 0;varcols = ["Time", "Day", "CPU", "%usr", "%nice", "%sys", "%iowait", "%irq", "%soft", "%steal", "%guest", "%gnice", "%idle"];mpstat.stdout.on (' Data ',function(data) {varstr =data.tostring (); if(Line > 2) { vararr = Str.split (/\s+/); Console.log (arr[0]+ "" +cols[3]+ "" +arr[3]); }Else{ Line++; }}); Mpstat.stderr.on (' Data ',function(data) {Console.log (' stderr: ' +( data);}); Mpstat.on (' Exit ',function(code) {Console.log (' Child process exited with code ' +code);});
To run the program:
~ node Mpstat.js11:47:57%usr 96.7511:47:58%usr 96.5211:47:59%usr 96.7511:48:00%usr 96.2511:48:01%usr 96.7411 : 48:02%usr 96.5111:48:03%usr 96.7411:48:04%usr 96.51
This completes the system data collection, we can store the collected data in the database, through the websocket and so on the direct output browser front-end to display the data.
2.2 EXEC function
The EXEC function is a friendly package for spawn, which adds shell command parsing and can embed complex commands directly, such as pipe usage cat spawn.js exec.js | Wc.
I first try the WC command to count the number of files in the current directory, corresponding to 3 columns of bytes, word count, number of lines.
~ WC * 9 275 exec.js 878 mpstat.js 343 spawn.js 165 1496 Total ~ Cat *.js | WC 1496 165
Next, we use the EXEC function to use the Linux Pipeline command.
~ vi exec.jsvar childprocess = require (' child_process '); var function (Error, stdout, stderr) { if (error) { console.log (error.stack); Console.log (' Error code: ' +error.code '); } Console.log (' child Process STDOUT: ' +STDOUT);});
To run the program:
~ node Exec.jschild Process STDOUT: 165 1496
The output is similar to the Linux command, and when you use Exec, the command can be written as a complete string without having to be written as multiple parameter arrays in the form of a spawn function. Finally, by a callback function to return, more in line with JavaScript function call habits, usually we can use exec to replace the use of spawn.
2.3 ExecFile function
The execfile function executes a specific program directly, with parameters passed in as an array and not interpreted by bash, thus having high security. ExecFile is similar to the parameters of spawn, and it is necessary to specify the commands and arguments to execute separately, but you can accept a callback function the same as the exec callback function.
Let's look at an example of a execfile function.
~ vi execfile.jsvar childprocess = require (' child_process '); var path = "." ; Childprocess.execfile (function (err, result) { Console.log (Result)});
Run the program
~16-rw-r--r--1 root root 527 mar 13:23 execfile.js-rw-r--r--1 root root 275 Mar 13:11 EXEC.J s-rw-r--r--1 root root 878 mar 11:53 mpstat.js-rw-r--r--1 root root 343 Mar 11:11 spawn.js
So, when do you use EXEC and when do you use execfile?
If the command arguments are entered by the user, there is a security risk for the EXEC function because the shell runs multiple lines of command, such as ' ls-l. PWD, which are separated by commas, are then run by the system. However, when using the Exefile command, commands and parameters are divided to prevent the security risk of parameter injection.
Let's test it with a program.
~VI execfile.js//execvarcmd = ' ls-l.; Pwdvarls = childprocess.exec (cmd,function(Error, stdout, stderr) {if(Error) {Console.log (error.stack); Console.log (' Error code: ' +Error.code); } console.log (' Child Process STDOUT: ' +stdout);});//execfilevarPath = ".; Pwd; Childprocess.execfile ('/bin/ls ', ['-l ', path],function(err, result) {Console.log (Result)});
Run the program
~ /bin/ls-L.; PWD/bin/falsenull, cmd: '/bin/ls-l.; PWD '16-rw-r--r--1 root root 547 mar 13:31 execfile.js-rw-r--r--1 root root 275 Mar 13:11 exe C.js-rw-r--r--1 root root 878 mar 11:53 mpstat.js-rw-r--r--1 root root 343 Mar 11:11 spawn.js /disk1/demo/nodejs-childprocess
As seen from the output, the EXEC function is executed normally, and the ExecFile function indicates that the parameter is wrong.
2.4 Fork
The fork function, which is used to run modules in a subprocess, such as fork ('./son.js ') is 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.
We have an example of a master process and subprocess communication, the main process file Main.js and the subprocess file son.js.
Creates a new master process file.
~ main.jsvar childprocess = require (' child_process '); var n = childprocess.fork ('./son.js '); N.on (function(m) { console.log (' Main Listen: 'son '});
Creates a new child process file.
~ vi son.jsprocess.on (function(m) { console.log (' son Listen: 'Conan '});
To run the program:
~ node Main.jsmain Listen: ' Conan' son '}
Main.js initiates a subprocess son.js, passing data between two processes through process. We check the system process to see if there are really two processes.
~ ps-aux| grep noderoot 22777 0.2 0.1 603240 13252 pts/3 sl+ 14:25 0:00 node main.jsroot 22782 0.2 0.1 603540 13516 pts/3 sl+ 14:25 0:00/usr/local/bin/node./son.js
There are 2 node processes, node Main.js and node/son.js, respectively.
Mastering the communication between the processes, we can do more things, such as a node. JS multi-Process Manager, scheduler and so on. The node program is so straightforward compared to multithreaded management or process scheduling in Java. I have been very clearly aware of the programming language in progress!!
From: http://blog.fens.me/nodejs-child-process/
node. JS Process Communication Module Child_process