Node generation 4

Source: Internet
Author: User
Process Management

Nodejs can perceive and control the running environment and status of its own processes, or create sub-processes and work with them. This allows nodejs to combine multiple programs to complete a job, and act as glue and scheduler. In addition to the related nodejs built-in modules, this chapter also focuses on typical use cases.

Open door

How to Use nodejs to call terminal commands to simplify directory copying

var child_process = require(‘child_process‘);var util = require(‘util‘);function copy(source, target, callback) {    child_process.exec(        util.format(‘cp -r %s/* %s‘, source, target), callback);}copy(‘a‘, ‘b‘, function (err) {    // ...});

The code above shows that the sub-process runs asynchronously and returns the execution result through the callback function.

APIS

Which Process Management APIs does nodejs provide?

Process

Any process has the command line parameters used to start the process, standard input and output, running permissions, running environment, and running status. In nodejs, you can useprocessObjects perceive and control all aspects of nodejs processes. Note that,processIt is not a built-in module, but a global object, so it can be directly used anywhere

Child Process

Usechild_processThe module can create and control sub-processes. The core API provided by this module is.spawnAnd other APIs are further encapsulated for specific use scenarios.

Cluster

clusterThe module ischild_processFurther encapsulation of the module is dedicated to solving the problem that the single-process nodejs web server cannot fully utilize the multi-core CPU. This module simplifies the development of multi-process server programs, allows a worker process to run on each core, and uniformly monitors ports and distributes requests through the main process.

Application scenarios

The APIS related to process management are rather boring to introduce separately. Therefore, we will introduce the usage of some important APIs in some typical application scenarios.

How to obtain command line parameters

In nodejs, you can useprocess.argvObtain command line parameters. But surprisingly,nodeThe execution program path and the main module File Path are fixedargv[0]Andargv[1]The First Command Line Parameterargv[2]Start. To makeargvIt is more natural to use and can be handled as follows

function main(argv) {    // ...}main(process.argv.slice(2));
How to exit the program

Generally, a program Exits normally after it completes all the tasks. The exit status code of the program is0. Or an exception occurs when a program is running, and the exit status code of the program is not equal0. If an exception is caught in the code, but the program should not continue to run, You need to exit immediately and set the exit status code to a specified number, such1, You can follow the methods below

try {    // ...} catch (err) {    // ...    process.exit(1);}
How to Control Input and Output

The standard input stream (stdin), a standard output stream (stdout), and a standard error stream (stderr) of the nodejs program correspondprocess.stdin,process.stdoutAndprocess.stderrThe first is read-only data streams, and the last two are write-only data streams. You can perform operations on these data streams as needed. For example,console.logYou can achieve this by using the following methods:

function log() {    process.stdout.write(        util.format.apply(util, arguments) + ‘\n‘);}
How to downgrade Permissions

In Linux, we know that the root permission is required to listen to ports below 1024. However, once the port listening is completed, it is recommended that the program run under the root permission to have security risks. The following is an example.

http.createServer(callback).listen(80, function () {    var env = process.env,        uid = parseInt(env[‘SUDO_UID‘] || process.getuid(), 10),        gid = parseInt(env[‘SUDO_GID‘] || process.getgid(), 10);    process.setgid(gid);    process.setuid(uid);});

Note the following points in the preceding example:

  • IfsudoIf the root permission is obtained, the UID and gid of the user running the program are stored in the environment variable.SUDO_UIDAndSUDO_GIDInside. Ifchmod +sTo obtain the root permission, the UID and gid of the user running the program can be directly obtained throughprocess.getuidAndprocess.getgidMethod acquisition
  • process.setuidAndprocess.setgidMethod accept onlynumberType Parameters
  • When downgrading, you must first drop the GID and then the UID; otherwise, you will not be authorized to change the program's GID in reverse order.
How to create a sub-process

The following is an example of creating a nodejs sub-process.

var child = child_process.spawn(‘node‘, [ ‘xxx.js‘ ]);child.stdout.on(‘data‘, function (data) {    console.log(‘stdout: ‘ + data);});child.stderr.on(‘data‘, function (data) {    console.log(‘stderr: ‘ + data);});child.on(‘close‘, function (code) {    console.log(‘child process exited with code ‘ + code);});

In the preceding example.spawn(exec, args, options)Method. This method supports three parameters. The first parameter is the execution file path, which can be the relative or absolute path of the execution file, or the execution file name that can be found according to the PATH environment variable. In the second parameter, each member in the array corresponds to a command line parameter in order. The third parameter is optional. It is used to configure the execution environment and behavior of sub-processes.

In addition.stdoutAnd.stderrAccess the output of the sub-process,options.stdioDifferent fields can be configured to redirect the input and output of a child process to any data stream, or allow the child process to share the standard input and output stream of the parent process, or directly ignore the input and output of the child process.

How to communicate between processes

In Linux, processes can communicate with each other through signals. The following is an example

/* parent.js */var child = child_process.spawn(‘node‘, [ ‘child.js‘ ]);child.kill(‘SIGTERM‘);/* child.js */process.on(‘SIGTERM‘, function () {    cleanUp();    process.exit(0);});

In the preceding example, the parent process passes.killMethod to sendSIGTERMSignal, sub-process monitoringprocessObjectSIGTERMEvent Response signal. Do not be.killThe method name is confusing. In essence, this method is used to send signals to the process. What the process will do after receiving the signal depends on the type of signal and the code of the process.

In addition, if both parent and child processes are node. js processes, data can be transmitted in two-way through IPC (inter-process communication. The following is an example

/* parent.js */var child = child_process.spawn(‘node‘, [ ‘child.js‘ ], {        stdio: [ 0, 1, 2, ‘ipc‘ ]    });child.on(‘message‘, function (msg) {    console.log(msg);});child.send({ hello: ‘hello‘ });/* child.js */process.on(‘message‘, function (msg) {    msg.hello = msg.hello.toUpperCase();    process.send(msg);});

As you can see, when a parent process creates a child processoptions.stdioTheipcAfter an IPC channel is enabled, you can listen tomessageThe event receives messages from the sub-process and passes.sendMethod to send messages to sub-processes. On the sub-process side, you canprocessObject ListeningmessageThe event receives messages from the parent process and passes.sendMethod to send messages to the parent process. During data transmission, data is first used on the sender.JSON.stringifyMethod serialization, and then useJSON.parseMethod deserialization

How to daemon sub-Processes

A daemon is generally used to monitor the running status of a working process. When a working process does not exit normally, it is restarted to ensure uninterrupted operation of the working process. The following is an implementation method:

/* daemon.js */function spawn(mainModule) {    var worker = child_process.spawn(‘node‘, [ mainModule ]);    worker.on(‘exit‘, function (code) {        if (code !== 0) {            spawn(mainModule);        }    });}spawn(‘worker.js‘);
Asynchronous programming

The biggest selling point of node. JS is the event mechanism and asynchronous Io. It cannot be said that node. js has actually been learned without understanding asynchronous programming.

Callback

In code, the direct embodiment of asynchronous programming is callback. Asynchronous programming relies on callback, but it cannot be said that the program will be asynchronized after callback is used.

function heavyCompute(n, callback) {    var count = 0,        i, j;    for (i = n; i > 0; --i) {        for (j = n; j > 0; --j) {            count += 1;        }    }    callback(count);}heavyCompute(10000, function (count) {    console.log(count);});console.log(‘hello‘);-- Console ------------------------------100000000hello

The callback function in the above Code is still executed before the subsequent code. JS itself runs in a single thread. It is impossible to run other code when a piece of code is not finished yet. Therefore, there is no concept of asynchronous execution.

However, if a function is used to create another thread or process, and do something in parallel with the main JS thread, and notify the main JS thread after the process is completed, the situation is different. Let's take a look at the following code:

setTimeout(function () {    console.log(‘world‘);}, 1000);console.log(‘hello‘);-- Console ------------------------------helloworld

This time, we can see that the callback function is executed in subsequent code. As mentioned above, JS itself is single-threaded and cannot be executed asynchronously. Therefore, we can consider thatsetTimeoutThe special functions provided by the runtime environment outside the JS specification are used to create a parallel thread and return immediately, so that the main JS process can then execute subsequent code, and then execute the callback function after receiving the notification from the parallel process. BesidessetTimeout,setIntervalThese common functions includefs.readFileAsynchronous API

In addition, we still return to the fact that JS is running in a single thread, which determines that JS cannot execute other code, including the callback function, before executing a piece of code. That is to say, even if the parallel thread completes the work, it notifies the main JS thread to execute the callback function. The callback function can be executed only when the main JS thread is idle. The following is an example.

function heavyCompute(n) {    var count = 0,        i, j;    for (i = n; i > 0; --i) {        for (j = n; j > 0; --j) {            count += 1;        }    }}var t = new Date();setTimeout(function () {    console.log(new Date() - t);}, 1000);heavyCompute(50000);-- Console ------------------------------8520

The callback function that should be called in one second is greatly delayed because the main JS thread is busy running other code.

Code Design Mode

Asynchronous programming has many unique code design patterns. To achieve the same function, the code written in synchronous mode and asynchronous mode is significantly different.

Function return value

It is very common to use the output of one function as the input of another function. In the synchronous mode, the code is generally written as follows:

var output = fn1(fn2(‘input‘));// Do something.

In asynchronous mode, because the function execution result is passed through the callback function instead of the return value, the code is generally written as follows:

fn2(‘input‘, function (output2) {    fn1(output2, function (output1) {        // Do something.    });});

This method is used to set a callback function with more than one callback function, which can be easily written.>Shape code

Traverse Arrays
var len = arr.length,    i = 0;for (; i < len; ++i) {    arr[i] = sync(arr[i]);}// All array items have processed.

If the function is executed asynchronously, the above Code cannot guarantee that all array members are processed after the loop ends. If the array members must be processed in serial mode, asynchronous code is generally written as follows:

(function next(i, len, callback) {    if (i < len) {        async(arr[i], function (value) {            arr[i] = value;            next(i + 1, len, callback);        });    } else {        callback();    }}(0, arr.length, function () {    // All array items have processed.}));

The above code is passed into the next array member and starts the next round of execution after the asynchronous function is executed once and the execution result is returned. After all array members are processed, the subsequent code execution is triggered by callback.

If the array members can be processed in parallel, but the subsequent code still needs to be executed after all array members are processed, the asynchronous code will be adjusted to the following form:

(function (i, len, count, callback) {    for (; i < len; ++i) {        (function (i) {            async(arr[i], function (value) {                arr[i] = value;                if (++count === len) {                    callback();                }            });        }(i));    }}(0, arr.length, 0, function () {    // All array items have processed.}));

Compared with the version of asynchronous serial traversal, the above Code processes all array members in parallel and uses counter variables to determine when all array members are processed.

Exception Handling

 

Node generation 4

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.