[转]nodejs中的process模块--child_process.exec
1.process是一个全局进程,你可以直接通过process变量直接访问它。
process实现了EventEmitter接口,exit方法会在当进程退出的时候执行。因为进程退出之后将不再执行事件循环,所有只有那些没有回调函数的代码才会被执行。
在下面例子中,setTimeout里面的语句是没有办法执行到的。
1 process.on(‘exit‘, function () { 2 setTimeout(function () { 3 console.log(‘This will not run‘); 4 }, 100); 5 console.log(‘exit‘); 6 }); //结果打印出exit
2.在你接触node之后,你就会发现那些影响了主事件循环的异常会把整个node进程宕掉的。
这会是相当严重的问题,所以process提供了另外一个有用的事件uncaughtException来解决这个问题,他会把异常抓取出来供你处理。
1 process.on(‘uncaughtException‘, function (err) { 2 console.log(‘Caught exception: ‘ + err); 3 }); 4 setTimeout(function () { 5 console.log(‘This will still run.‘); 6 }, 500); 7 // Intentionally cause an exception, but don‘t catch it. 8 nonexistentFunc(); 9 console.log(‘This will not run.‘);
我们来看上面的例子,我们注册了uncaughtException事件来捕捉系统异常。执行到nonexistentFunc()时,因为该函数没有定义所以会抛出异常。
因为javascript是解释性的语言,nonexistentFunc()方法上面的语句不会被影响到,他下面的语句不会被执行。所以他的执行结果如下:
Caught exception: ReferenceError: nonexistentFunc is not defined
This will still run.
1.child_process是Node.js的一个十分重要的模块,通过它可以实现创建多进程,以利用多核计算资源。
child_process模块提供了四个创建子进程的函数,分别是spawn,exec,execFile和fork。其中spawn是最原始的创建子进程的函数,其他三个都是对spawn不同程度的封装。
spawn只能运行指定的程序,参数需要在列表中给出,相当于execvp系统函数,而exec可以直接运行复杂的命令。
child_process.spawn(command, [args], [options])
child_process.exec(command, [options], callback)
例如要运行ls
-lh
/usr,使用spawn需要写成spawn(‘ls‘,
[‘-lh‘,
‘/usr‘]),而exec只需exec(‘ls
-lh
/usr‘)。
exec的实现原理是启动了一个系统shell来解析参数,因此可以是非常复杂的命令,包括管道和重定向。
此外,exec还可以直接接受一个回调函数作为参数,回调函数有三个参数,分别是err, stdout , stderr,非常方便直接使用,例如:
1 require(‘child_process‘).exec( ‘ls -lh /usr‘ , function(err, stdout , stderr ) { 2 console.log( stdout ); 3 });
如果使用spawn,则必须写成:
2.fork函数用于直接运行Node.js模块,例如fork(‘./child.js‘),相当于spawn(‘node‘,
[‘./child.js‘])。
与默认的spawn不同的是,fork会在父进程与子进程直接建立一个IPC管道,用于父子进程之间的通信。例如
1 var n = require(‘child_process‘).fork( ‘./child.js‘); 2 n. on ( ‘message‘, function(m) { 3 console. log ( ‘PARENT got message:‘, m); 4 }); 5 n.send({ hello: ‘world‘ });
child.js的内容
1 process. on ( ‘message‘, function(m) { 2 console. log ( ‘CHILD got message:‘, m); 3 }); 4 process.send({ foo: ‘bar‘ });
结果:
1 PARENT got message: { foo: ‘bar‘ } 2 CHILD got message: { hello: ‘world‘ }
3.fork函数有一个问题,就是它只能运行JavaScript代码,如果你喜欢用CoffeeScript(或者其他任何编译到js的语言),是无法通过fork调用的。
一个简单的方法是把代码编译到JavaScript再运行,但是很不方便,有没有什么办法呢?答案是可以的,
child_process.spawn(command, [args], [options])
通过把options参数的stdio设为[‘ipc‘],
即可在父子进程之间建立IPC管道。例如子进程使用CoffeeScript:
1 child_process = require (‘child_process‘); 2 options ={stdio: [‘ipc‘] }; 3 child = child_process.spawn(‘coffee‘, [‘./child.coffee‘], options);
其中只要把spawn的第一个参数设置为运行对应脚本的解释器,即可运行,例如使用Continuation.js,
只需child = child_process.spawn(‘continuation‘,
[‘./child.coffee‘], options)。
参考:
http://www.cnblogs.com/yuyutianxia/p/3271733.html
