Node.js之child_process(子进程)

背景知识:

    Every node.js process is single threaded by design. Therefore to get multiple threads, you have to have multiple processes(As some other posters have pointed out, there are also libraries you can link to that will give you the ability to work with threads in Node)

    每一个 node.js 的进程都是单线程的。因此要想有多个线程,只能创建多个进程。
    当然,已经出现了,可以在一个进程中创建多个线程的库。

    但,本文锁定的是:如何使用 node.js 创建多个进程。


1、child_process

    child_process 模块提供了类似于,但不完全相同于 popen(3) 的创建子进程的方法。


2、什么是 popen(3)

    popen(3) 是一个 Linux 系统的命令。

    popen() 函数用于创建一个进程,它的实现方法通过创建 pipe, forking, 然后调用 shell 。
    由于 pipe 定义时是单向的,所以只能执行单向操作:或进行读操作,或进行写操作;但不能同时进行读写操作。


3、child_process API 说明

    child_process 拥有3个流(这3个流可以被父进程的 stdio 流使用 ):

        1)输入流:child.stdin
        2)输出流:child.stdout
        3)错误流:child.stderr

   
    Node.js 提供的 child_process 主要有下面3种用法:

        1)exec − child_process.exec() 方法在 shell 中运行一个系统命令,并缓存输出的结果。
        2)spawn − child_process.spawn() 使用给定的系统命令启动一个子线程。
        3)fork − child_process.fork() 是 child_process.spawn()的特别情况下的用法,也是启动一个子线程。


4、使用实例


//task.js

console.log('processing in background...');

for(var i = 0; i < 99999999999; i++){} // simulate waiting for a long time.

console.log("processing finished!");

//end



//app.js

var express = require('express');
var app = express();
var child_process = require('child_process');

app.get('/', function (req, res) {
    console.log("A User require: Hello World!");
    res.send('Hello World!');
});

app.get('/echo', function (req, res) {
    var worker_process = child_process.fork("task.js");
    worker_process.on('close', function (code) {
       console.log('child process exited with code ' + code);
    });
});

app.use(function(err, req, res, next) {
    console.error(err.stack);
    res.status(404).send('Resource Not Found!');
    res.status(500).send('System Error!');
    next();
});

app.listen(3000, function () {
    console.log('Server app listening on port 3000!');
});





改进版:

    增加了请求超时,返回。


//app.js

var express = require('express');
var app = express();
var child_process = require('child_process');
var port = 3000;

app.get('/', function (req, res) {
    console.log("A User require: Hello World!");
    res.send('Hello World!');
});

app.get('/echo',function(req,res){
    var run = function(){
        var isTimeout = false,
            isCallback = false;
        return function(){
            var worker_process = child_process.fork('./task.js');
            worker_process.on('message',function(data){
                if(isTimeout) return;
                isCallback = true;
                res.send(data);
            });
            setTimeout(function(){
                if(isCallback) return;
                isTimeout = true;
                worker_process.kill();
                res.send({result:'time is out'});
            },1000*60);
        }
    }();
    run();
});

app.use(function(err, req, res, next) {
    console.error(err.stack);
    res.status(404).send('Resource Not Found!');
    res.status(500).send('System Error!');
    next();
});

app.listen(port, function () {
    console.log('Server app listening on port ' + port );
});








引用:

POPEN(3) - Linux Programmer's Manual
http://man7.org/linux/man-pages/man3/popen.3.html

How to create threads in nodejs
http://stackoverflow.com/a/18613311/2893073

Node.js - Scaling Application
https://www.tutorialspoint.com/nodejs/nodejs_scaling_application.htm

Node.js - 子进程
https://nodejs.org/api/child_process.html

Node.js - Cluster
https://nodejs.org/api/cluster.html






猜你喜欢

转载自lixh1986.iteye.com/blog/2327082