虽然node对操做系统作了不少抽象的工做,可是你仍是能够直接和他交互,好比和系统中已经存在的进程进行交互,建立工做子进程。node是一个用于事件循环的线程,可是你能够在这个事件循环以外建立其余的进程(线程)参与工做。javascript
进程模块java
process模块容许你得到或者修改当前node进程的设置,不想其余的模块,process是一个全局进程(node主进程),你能够直接经过process变量直接访问它。node
process实现了EventEmitter接口,exit方法会在当进程退出的时候执行。由于进程退出以后将再也不执行事件循环,全部只有那些没有回调函数的代码才会被执行。在下面例子中,setTimeout里面的语句是没有办法执行到的。linux
process.on('exit', function () { setTimeout(function () { console.log('This will not run'); }, 100); console.log('Bye.'); });
在你接触node以后,你就会发现那些影响了主事件循环的异常会把整个node进程宕掉的。这会是至关严重的问题,因此process提供了另一个有用的事件uncaughtException来解决这个问题,他会把异常抓取出来供你处理。web
process.on('uncaughtException', function (err) { console.log('Caught exception: ' + err); }); setTimeout(function () { console.log('This will still run.'); }, 500); // Intentionally cause an exception, but don't catch it. nonexistentFunc(); console.log('This will not run.');
咱们来看上面的例子,咱们注册了uncaughtException事件来捕捉系统异常。执行到nonexistentFunc()时,由于该函数没有定义因此会抛出异常。由于javascript是解释性的语言,nonexistentFunc()方法上面的语句不会被影响到,他下面的语句不会被执行。因此他的执行结果以下:shell
Caught exception: ReferenceError: nonexistentFunc is not defined This will still run.
var http = require('http'); var server = http.createServer(function(req,res) { res.writeHead(200, {}); res.end('response'); badLoggingCall('sent response'); console.log('sent response'); }); process.on('uncaughtException', function(e) { console.log(e); }); server.listen(8080);
在这里例子中咱们建立了一个web服务器,当处理完请求以后,咱们会执行badLoggingCall()方法。由于这个方法不存在,因此会有异常抛出。可是咱们注册的uncaughtException事件会对异常作出处理,这样服务器不会受到影响得以继续运行。咱们会在服务器端记录错误日志。服务器
[ReferenceError: badLoggingCall is not defined]
与当前进程交互函数
node提供了一些process的属性,以下:oop
process.version:包含当前node实例的版本号;ui
process.installPrefix:包含安装路径;
process.platform:列举node运行的操做系统的环境,只会显示内核相关的信息,如:linux2, darwin,而不是“Redhat ES3” ,“Windows 7”,“OSX 10.7”等;
process.uptime():包含当前进程运行的时长(秒);
process.getgid(), process.setgid():获取或者设置group id;
process.getuid(), process.setuid():获取或者设计user id;
process.pid:获取进程id;
process.title:设置进程名称;
process.execPath:当前node进程的执行路径,如:/usr/local/bin/node;
process.cwd():当前工做目录;
process.memoryUsage():node进程内存的使用状况,rss表明ram的使用状况,vsize表明总内存的使用大小,包括ram和swap;
process.heapTotal,process.heapUsed:分别表明v8引擎内存分配和正在使用的大小。
事件循环和ticker
node中提供了process.nextTick()方法,容许你访问事件循环和延时那你的工做。他有点相似于setTimeout(),他会在下次tick的时候执行,并且每隔一段事件就会执行一次。咱们这里有个例子:
var http = require('http'); var s = http.createServer(function(req, res) { res.writeHead(200, {}); res.end('foo'); console.log('http response'); process.nextTick(function(){console.log('tick')}); }); s.listen(8000);
当请求来的时候,会记录日志‘http response’和‘tick’,当没有请求的时候,每隔一段事件会执行事件循环,会输出tick。
此外,nextTick建立的回调函数具备隔离性,他们之间不会相互影响。
process.on('uncaughtException', function(e) { console.log(e); }); process.nextTick(function() { console.log('tick'); }); process.nextTick(function() { iAmAMistake(); console.log('tock'); }); process.nextTick(function() { console.log('tick tock'); }); console.log('End of 1st loop');
在这个例子中,首先输出‘End of 1st loop’,而后顺序的输出nextTick的回调函数,第一个会正常输出‘tick’,第二个是一个故意设置的异常会输出异常信息,不会输出‘tock’,由于nextTick回调函数的隔离性,第三个任然会输出‘tick tock’。结果以下:
End of 1st loop tick [ReferenceError: iAmAMistake is not defined] tick tock
子进程
node提供了child_process模块,容许你为主进程建立子进程,这样你就可使用更多的服务器资源,使用更多的cpu,这些概念在前面的章节有介绍。node提供了child_process. spawn()和child_process. exec()为你实现这一功能,下面咱们就单独介绍。
child_process.exec( )
咱们来看exec的一个简单例子,他建立了一个子进程,第一个参数是一个shell命令,第二个参数是回调函数,处理返回结果。
var cp = require('child_process'); cp.exec('ls -l', function(e, stdout, stderr) { if(!e) { console.log(stdout); console.log(stderr); } });
exec()还能够传options的参数:
var options = { encoding: 'utf8', timeout: 0, maxBuffer: 200 * 1024, killSignal: 'SIGTERM', setsid: false, cwd: null, env: null }; var cp = require('child_process'); cp.exec('ls -l', options, function(e, stdout, stderr) { if(!e) { console.log(stdout); console.log(stderr); } });
encoding:I/O流的编码格式;
timeout:进程超时时间;
killSignal:当时间或者缓冲区超限时终止进程的信号;
maxBuffer:stdout或stderr可增加的最大值;
setsid:决定在进程中是否建立一个新的会话;
cwd:进程的初始工做目录,为null时表示使用node的当前工做目录;
env:进程的环境变量。
child_process.spawn( )
child_process.spawn( )比child_process.exec( )更增强大和灵活,例子以下:
var cp = require('child_process'); var cat = cp.spawn('cat'); cat.stdout.on('data', function(d) { console.log(d.toString()); }); cat.on('exit', function() { console.log('kthxbai'); }); cat.stdin.write('meow'); cat.stdin.end();