NodeJS子进程简介
NodeJS 子进程提供了与系统交互的重要接口,其主要 API 有:
标准输入、标准输出及标准错误输出的接口
child.stdin 获取标准输入
child.stdout 获取标准输出
child.stderr 获取标准错误输出
获取子进程的PID:child.pid
提供生成子进程的重要方法:child_process.spawn(cmd, args=[], [options])
提供直接执行系统命令的重要方法:child_process.exec(cmd, [options], callback)
提供杀死进程的方法:child.kill(signal=’SIGTERM’)
实例一:利用子进程获取系统内存使用情况
将以下代码保存为 free.js:
free = spawn('free', ['-m']);
// 捕获标准输出并将其打印到控制台
free.stdout.on('data', function (data) {
console.log('标准输出:\n' + data);
});
// 捕获标准错误输出并将其打印到控制台
free.stderr.on('data', function (data) {
console.log('标准错误输出:\n' + data);
});
// 注册子进程关闭事件
free.on('exit', function (code, signal) {
console.log('子进程已退出,代码:' + code);
});
执行代码后的结果:
标准输出:
total used free shared buffers cached
Mem: 3949 1974 1974 0 135 959
-/+ buffers/cache: 879 3070
Swap: 3905 0 3905
子进程已退出,代码:0
以上输出相当与在命令行执行:free -m 命令。
通过这个简单的例子我们已经对子进程的使用有所了解,下面再来一个示例,用于演示exec 的使用方法。
实例二:利用子进程统计系统登录次数
将下面代码保存为 last.js
last = exec('last | wc -l');
last.stdout.on('data', function (data) {
console.log('标准输出:' + data);
});
last.on('exit', function (code) {
console.log('子进程已关闭,代码:' + code);
});
执行代码:
$ node last.js
子进程已关闭,代码:0
其与直接在命令行输入:last | wc -l 的结果是一样的。
————————————————————————————————————————————————————————————————————————————————————
child_process是Node.js的一个十分重要的模块,通过它可以实现创建多进程,以利用多核计算资源。
Node.js 0.8的child_process模块提供了四个创建子进程的函数,分别是spawn,exec,execFile和fork。其中spawn是最原始的创建子进程的函数,其他三个都是对spawn不同程度的封装。spawn只能运行指定的程序,参数需要在列表中给出,相当于execvp系统函数,而exec可以直接运行复杂的命令。
例如要运行ls -lh /usr,使用spawn需要写成spawn(‘ls’, [‘-lh’, ‘/usr’]),而exec只需exec(‘ls -lh /usr’)。exec的实现原理是启动了一个系统shell来解析参数,因此可以是非常复杂的命令,包括管道和重定向。此外,exec还可以直接接受一个回调函数作为参数,回调函数有三个参数,分别是err, stdout, stderr,非常方便直接使用,例如:
console.log(stdout);
});
如果使用spawn,则必须写成:
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) {
console.log(data);
});
execFile与spawn的参数相似,也需要分别指定执行的命令和参数,但可以接受一个回调函数,与exec的回调函数相同。它与exec的区别在于不启动独立的shell,因此相比更加轻量级。
fork函数用于直接运行Node.js模块,例如fork(‘./child.js’),相当于spawn(‘node’, [‘./child.js’])。与默认的spawn不同的是,fork会在父进程与子进程直接建立一个IPC管道,用于父子进程之间的通信。例如:
n.on('message', function(m) {
console.log('PARENT got message:', m);
});
n.send({ hello: 'world' });
child.js的内容:
console.log('CHILD got message:', m);
});
process.send({ foo: 'bar' });
其中父进程调用fork函数获取一个返回值,作为子进程的句柄,通过send函数发送信息,on(‘message’)监听返回的信息,子进程通过内置的process对象相同的方法与父进程通信。
fork函数有一个问题,就是它只能运行JavaScript代码,如果你喜欢用CoffeeScript(或者其他任何编译到js的语言),是无法通过fork调用的。一个简单的方法是把代码编译到JavaScript再运行,但是很不方便,有没有什么办法呢?
答案是可以的,还是得回到spawn函数。spawn函数除了接受command, args外,还接受一个options参数。通过把options参数的stdio设为[‘ipc’],即可在父子进程之间建立IPC管道。例如子进程使用CoffeeScript:
options =
stdio: ['ipc']
child = child_process.spawn 'coffee', ['./child.coffee'], options
其中只要把spawn的第一个参数设置为运行对应脚本的解释器,即可运行,例如使用Continuation.js,只需child = child_process.spawn(‘continuation’, [‘./child.coffee’], options)。
- 本文固定链接: http://www.sa-log.com/149.html
- 转载请注明: 王, 帅 于 我的系统记录 发表