詳解nodejs中的process進程
雖然node對操作系統(tǒng)做了很多抽象的工作,但是你還是可以直接和他交互,比如和系統(tǒng)中已經(jīng)存在的進程進行交互,創(chuàng)建工作子進程。node是一個用于事件循環(huán)的線程,但是你可以在這個事件循環(huán)之外創(chuàng)建其他的進程(線程)參與工作。
進程模塊
process模塊允許你獲得或者修改當(dāng)前node進程的設(shè)置,不想其他的模塊,process是一個全局進程(node主進程),你可以直接通過process變量直接訪問它。
process實現(xiàn)了EventEmitter接口,exit方法會在當(dāng)進程退出的時候執(zhí)行。因為進程退出之后將不再執(zhí)行事件循環(huán),所有只有那些沒有回調(diào)函數(shù)的代碼才會被執(zhí)行。在下面例子中,setTimeout里面的語句是沒有辦法執(zhí)行到的。
process.on('exit', function () { setTimeout(function () { console.log('This will not run'); }, 100); console.log('Bye.'); });
在你接觸node之后,你就會發(fā)現(xiàn)那些影響了主事件循環(huán)的異常會把整個node進程宕掉的。這會是相當(dāng)嚴重的問題,所以process提供了另外一個有用的事件uncaughtException來解決這個問題,他會把異常抓取出來供你處理。
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事件來捕捉系統(tǒng)異常。執(zhí)行到nonexistentFunc()時,因為該函數(shù)沒有定義所以會拋出異常。因為javascript是解釋性的語言,nonexistentFunc()方法上面的語句不會被影響到,他下面的語句不會被執(zhí)行。所以他的執(zhí)行結(jié)果如下:
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);
在這里例子中我們創(chuàng)建了一個web服務(wù)器,當(dāng)處理完請求之后,我們會執(zhí)行badLoggingCall()方法。因為這個方法不存在,所以會有異常拋出。但是我們注冊的uncaughtException事件會對異常做出處理,這樣服務(wù)器不會受到影響得以繼續(xù)運行。我們會在服務(wù)器端記錄錯誤日志。
[ReferenceError: badLoggingCall is not defined]
與當(dāng)前進程交互
node提供了一些process的屬性,如下:
process.version:包含當(dāng)前node實例的版本號;
process.installPrefix:包含安裝路徑;
process.platform:列舉node運行的操作系統(tǒng)的環(huán)境,只會顯示內(nèi)核相關(guān)的信息,如:linux2, darwin,而不是“Redhat ES3” ,“Windows 7”,“OSX 10.7”等;
process.uptime():包含當(dāng)前進程運行的時長(秒);
process.getgid(), process.setgid():獲取或者設(shè)置group id;
process.getuid(), process.setuid():獲取或者設(shè)計user id;
process.pid:獲取進程id;
process.title:設(shè)置進程名稱;
process.execPath:當(dāng)前node進程的執(zhí)行路徑,如:/usr/local/bin/node;
process.cwd():當(dāng)前工作目錄;
process.memoryUsage():node進程內(nèi)存的使用情況,rss代表ram的使用情況,vsize代表總內(nèi)存的使用大小,包括ram和swap;
process.heapTotal,process.heapUsed:分別代表v8引擎內(nèi)存分配和正在使用的大小。
事件循環(huán)和ticker
node中提供了process.nextTick()方法,允許你訪問事件循環(huán)和延時那你的工作。他有點類似于setTimeout(),他會在下次tick的時候執(zhí)行,而且每隔一段事件就會執(zhí)行一次。我們這里有個例子:
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);
當(dāng)請求來的時候,會記錄日志‘http response'和‘tick',當(dāng)沒有請求的時候,每隔一段事件會執(zhí)行事件循環(huán),會輸出tick。
此外,nextTick創(chuàng)建的回調(diào)函數(shù)具有隔離性,他們之間不會相互影響。
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的回調(diào)函數(shù),第一個會正常輸出‘tick',第二個是一個故意設(shè)置的異常會輸出異常信息,不會輸出‘tock',因為nextTick回調(diào)函數(shù)的隔離性,第三個任然會輸出‘tick tock'。結(jié)果如下:
End of 1st loop
tick
[ReferenceError: iAmAMistake is not defined]
tick tock
子進程
node提供了child_process模塊,允許你為主進程創(chuàng)建子進程,這樣你就可以使用更多的服務(wù)器資源,使用更多的cpu,這些概念在前面的章節(jié)有介紹。node提供了child_process. spawn()和child_process. exec()為你實現(xiàn)這一功能,下面我們就單獨介紹。
child_process.exec( )
我們來看exec的一個簡單例子,他創(chuàng)建了一個子進程,第一個參數(shù)是一個shell命令,第二個參數(shù)是回調(diào)函數(shù),處理返回結(jié)果。
var cp = require('child_process'); cp.exec('ls -l', function(e, stdout, stderr) { if(!e) { console.log(stdout); console.log(stderr); } });
exec()還可以傳options的參數(shù):
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:當(dāng)時間或者緩沖區(qū)超限時終止進程的信號;
maxBuffer:stdout或stderr可增長的最大值;
setsid:決定在進程中是否創(chuàng)建一個新的會話;
cwd:進程的初始工作目錄,為null時表示使用node的當(dāng)前工作目錄;
env:進程的環(huán)境變量。
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();
以上所述是小編給大家介紹的nodejs中的process進程,希望對大家有所幫助!
相關(guān)文章
node.js使用 http-proxy 創(chuàng)建代理服務(wù)器操作示例
這篇文章主要介紹了node.js使用 http-proxy 創(chuàng)建代理服務(wù)器,結(jié)合實例形式分析了node.js使用 http-proxy 創(chuàng)建代理服務(wù)器原理、具體步驟與相關(guān)注意事項,需要的朋友可以參考下2020-02-02Node中使用http-proxy-middleware實現(xiàn)代理跨域的方法步驟
本文主要介紹了Node中使用http-proxy-middleware實現(xiàn)代理跨域的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11Node.js中Path 模塊的介紹和使用示例小結(jié)
Node.js path 模塊提供了一些用于處理文件路徑的小工具,下面通過本文給大家介紹Node.js中Path 模塊的介紹和使用示例小結(jié),感興趣的朋友跟隨小編一起看看吧2024-05-05Node.js中,在cmd界面,進入退出Node.js運行環(huán)境的方法
今天小編就為大家分享一篇Node.js中,在cmd界面,進入退出Node.js運行環(huán)境的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05