Node.js 使用 child_process 实现多进程

nodejs是一种单线程模型,但是,使用nodejs的child_process模块可以实现多进程任务。利用child_process可以创建子进程,实现子进程和主进程之间的通信。

nodejs v0.12.7版本child_process提供以下同步和异步的方式创建进程:

异步创建:
    child_process.spawn(command[, args][, options])
    options.stdio
    options.detached
    options.customFds
    child_process.exec(command[, options], callback)
    child_process.execFile(file[, args][, options][callback])
    child_process.fork(modulePath[, args][, options])
同步创建:
    child_process.spawnSync(command[, args][, options])
    child_process.execFileSync(command[, args][, options])
    child_process.execSync(command[, options])

各函数及参数文档可见 文档

spawn 函数

例 1

var spawn = require('child_process').spawn,
    ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', function(data) {
    console.log('stdout: ' + data);
});

ls.stderr.on('data', function(data) {
    console.log('stderr: ' + data);
});

ls.on('close', function(code) {
    console.log('child process exited with code ' + code);
});

运行结果

-bash-4.1$ node child_process.js 
stdout: total 76K
dr-xr-xr-x.  2 root root  20K Jul 23 11:15 bin
drwxr-xr-x.  2 root root 4.0K Sep 23  2011 etc
drwxr-xr-x.  2 root root 4.0K Sep 23  2011 games
drwxr-xr-x. 53 root root 4.0K Nov 29  2014 include
dr-xr-xr-x. 26 root root 4.0K Nov 19  2014 lib
dr-xr-xr-x. 35 root root  20K Nov 29  2014 lib64
drwxr-xr-x. 12 root root 4.0K Nov 21  2014 libexec
drwxr-xr-x. 13 root root 4.0K Jan  6  2015 local
dr-xr-xr-x.  2 root root 4.0K Jun 16 15:33 sbin
drwxr-xr-x. 96 root root 4.0K May  7 09:48 share
drwxr-xr-x.  4 root root 4.0K Mar 27  2013 src
lrwxrwxrwx.  1 root root   10 Mar 27  2013 tmp -> ../var/tmp

child process exited with code 0

例 2 花式实现ps ax|grep child

var spawn = require('child_process').spawn,
    ps = spawn('ps', ['ax']),
    grep = spawn('grep', ['child']);

ps.stdout.on('data', function(data) {
    grep.stdin.write(data);
});

ps.stderr.on('data', function(data) {
    console.log('ps stderr: ' + data);
});

ps.on('close', function(code) {
    if (code !== 0) {
        console.log('ps process exited with code ' + code);
    }
    grep.stdin.end();
});

grep.stdout.on('data', function(data) {
    console.log('' + data);
});

grep.stderr.on('data', function(data) {
    console.log('grep stderr: ' + data);
});

grep.on('close', function(code) {
    if (code !== 0) {
        console.log('grep process exited with code ' + code);
    }
});

输出

-bash-4.1$ node child_process.js 
 9940 pts/4    Rl+    0:00 node child_process.js
12876 pts/4    T      0:00 vim child_process.js
30870 pts/4    T      0:00 vim child_process.js

exec 函数

例 1 统计文件字数,3列分别为 行数、字数、字节数

var exec = require('child_process').exec,
    child;

child = exec('cat child_process.js | wc', function(error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
        console.log('exec error: ' + error);
    }
}); 

输出

-bash-4.1$ node child_process.js 
stdout:      10      35     287

stderr: 

exec函数第二个可选参数默认值:

{ encoding: 'utf8',
  timeout: 0,
  maxBuffer: 200*1024,
  killSignal: 'SIGTERM',
  cwd: null,
  env: null }

exec函数不安全,使用用户输入作为参数时不应使用

execFile 函数

例 1

var childProcess = require('child_process');

childProcess.execFile('/bin/ls', ['-l', '.'], function(err, result) {
    console.log(result)
});

输出

-bash-4.1$ node child_process.js 
total 4
-rw-rw-r-- 1 dongshaoshuai dongshaoshuai 144 Jul 31 17:02 child_process.js

使用execFile安全防注入

fork 函数

fork 可以实现父进程和子进程的通信
main.js

var childProcess = require('child_process');
var child = childProcess.fork('./child.js');

child.on('message', function(msg) {
    console.log("Main on message: ", msg);
});

child.send({message: "I love you !"});

child.js

process.on('message', function(m) {
    console.log('Child listen:', m);
});

process.send({ message: 'You love me'});

运行main.js

-bash-4.1$ node main.js 
Child listen: { message: 'I love you !' }
Main on message:  { message: 'You love me' }

你可能感兴趣的:(Node.js,杂货)