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])
各函数及参数文档可见 文档
例 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
例 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函数不安全,使用用户输入作为参数时不应使用
例 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 可以实现父进程和子进程的通信
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' }