nodejs之process進程小記

雖然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();
相關文章
相關標籤/搜索