Node.js API —— process(進程)

// 說明
    Node API 版本爲 v0.10.31。
    中文參考:http://nodeapi.ucdok.com/#/api/http://blog.sina.com.cn/oleoneoy
    本段爲博主註解。

目錄

進程
    ○ Event: 'exit'
    ○ Event: 'uncaughtException'
    ○ Signal Events
    ○ process.stdout
    ○ process.stderr
    ○ process.stdin
    ○ process.argv
    ○ process.execPath
    ○ process.execArgv
    ○ process.abort()
    ○ process.chdir(directory)
    ○ process.cwd()
    ○ process.env
    ○ process.exit([code])
    ○ process.getgid()
    ○ process.setgid(id)
    ○ process.getuid()
    ○ process.setuid(id)
    ○ process.getgroups()
    ○ process.setgroups(groups)
    ○ process.initgroups(user, extra_group)
    ○ process.version
    ○ process.versions
    ○ process.config
    ○ process.kill(pid, [signal])
    ○ process.pid
    ○ process.title
    ○ process.arch
    ○ process.platform
    ○ process.memoryUsage()
    ○ process.nextTick(callback)
    ○ process.maxTickDepth
    ○ process.umask([mask])
    ○ process.uptime()
    ○ process.hrtime()

進程

    process 對象是一個全局對象,能在任何地方被訪問。它是一個 EventEmitter 實例。

Event: 'exit'

    當進程將要退出時發射。在這個時候沒有任何途徑來阻止退出事件循環,且當全部的 exit 監聽器運行完以後進程將會退出。所以,在本監聽器內你必須只使用同步的操做。這是一個很好的執行模塊狀態的檢驗的鉤子(好比用於單元測試上)。回調函數有一個參數,即進程的退出碼。
    監聽 exit 的例子:
1 process.on('exit', function(code) {
2   // do *NOT* do this
3   setTimeout(function() {
4     console.log('This will not run');
5   }, 0);
6   console.log('About to exit with code: ', code);
7 });

Event: 'uncaughtException'

    當一個異常一路冒泡到事件循環時發射。若是爲這個異常添加了一個監聽器,那麼默認的動做(打印堆棧信息並退出)將不會被觸發。
    監聽 uncaughtException 的例子:
 1 process.on('uncaughtException', function(err) {
 2   console.log('Caught exception: ' + err);
 3 });
 4 
 5 setTimeout(function() {
 6   console.log('This will still run.');
 7 }, 500);
 8 
 9 // Intentionally cause an exception, but don't catch it
10 nonexitstentFunc();
11 console.log('This will not run.');

    注意 uncaughtException 是一種很是粗魯的異常捕獲途徑且有可能在未來移除。
    不要使用它,使用 domains 取代。若是你使用了它,在每一個沒被正常捕獲的異常後重啓你的應用程序。
    不要使用它由於 node.js 至關於出了錯待會恢復從新開始。一個未捕獲的異常意味着你的應用程序——推而廣之 node.js 自己處於未知狀態。盲目地恢復意味着什麼事情都有可發生。
    假想當你正在升級系統時拔了電源線,而後恢復了。十次有九次都沒事發生——但在第十次,你的系統就崩了。
    你已經被警告過。
node

Signal Events

    當進程受到一個信號時發射。參看 sigaction(2) 列出的標註 POSIX 信號,例如 SIGINT,SIGHUP等。
    監聽 SIGINT 的例子:
1 // Start reading from stdin so we don't exit.
2 process.stdin.resume();
3 
4 process.on('SIGINT', function() {
5   console.log('Got SIGINT. Press Control-D to exit.');
6 });

    在大多數的終端程序中一個簡單的發送 SIGINT 信號的方法是使用 Control-C
    注意:
linux

  • SIGUSR1 被 node.js 保留用以啓動 debugger。能夠建立一個監聽器但那不會中止 debugger 的啓動。
  • SIGTERM 和 SIGINT 在非 Windows 平臺下有默認的監聽器,退出並在退出前重置終端 mode 爲128加信號數值。若是這兩信號之一建立了監聽器,它們的默認操做將會被移除(node 將永不退出)。
  • SIGPIPE 默認被忽略,他能夠建立監聽器。
  • SIGHUP 在 Windows 下當控制檯窗口被關閉時產生,在其餘平臺各個相似的條件下,參看 signal(7)。它能夠建立監聽器,然而 node 將在大約10秒後被 Windows 無條件終止。在非 Windows 平臺下,SIGHUP 的默認行爲是終止 node,但一旦建立了監聽器默認的行爲將被移除。
  • SIGTERM 在 Windows 下不支持,能夠被監聽。
  • SIGINT 從終端發送該信號能被全部平臺支持,且一般能夠用 CTRL+C 產生(即便這是可配置的)。當終端 raw 模式啓動時它不能被產生。
  • SIGBREAK 在 Windows 下當按下 CTRL+BREAK 時產生,在非 Windows 平臺下能夠別監聽,但沒有途徑能夠發送或產生它。
  • SIGWINCH 當控制檯改變大小時產生。在 Windows 下,這隻會發生在鼠標正在移動時向控制檯輸入,或刻度的 tty 在 raw 模式下使用。
  • SIGKILL 不可被監聽,在任何平臺下 node 都將無條件終止。
  • SIGSTOP 不可被監聽。

    注意 Windows 不支持發送信號,但 node 使用 process.kill()child_process.kill() 提供了一些模擬:——發送信號0能夠用來查找進程是否存在——發送 SIGINTSIGTERMSIGKILL 讓目標進程無條件退出。shell

process.stdout

    寫向標準輸出可寫流
    例子:console.log 的定義
1 console.log = function(d) {
2   process.stdout.write(d + '\n');
3 };

    process.stderrprocess.stdout 和 Node 中的其餘流不一樣,向它們寫入一般是阻塞的。npm

  • 當它們指向普通文件或 TTY 文件描述符時它們是阻塞的。
  • 當它們指向管道:
      ○ 在 Linux/Unix 下是阻塞的。
      ○ 在 Windows 下與其餘流同樣是非阻塞的。
    要檢驗 Node 是否運行在 TTY 上下文中,參看 process.stderrprocess.stdoutprocess.stdinisTTY 屬性:
 
$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false

$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false

    更多信息參看 tty 文檔api

process.stderr

    寫向標準錯誤輸出的可寫流。
    process.stderr 和 process.stdout 和 Node 中的其餘流不一樣,向它們寫入一般是阻塞的。
  • 當它們指向普通文件或 TTY 文件描述符時它們是阻塞的。
  • 當它們指向管道:
      ○ 在 Linux/Unix 下是阻塞的。
      ○ 在 Windows 下與其餘流同樣是非阻塞的。

process.stdin

    標準輸入的可寫流
    打開標準輸入並監聽兩個事件的例子:
 1 process.stdin.setEncoding('utf8');
 2 
 3 process.stdin.on('readable', function() {
 4   var chunk = process.stdin.read();
 5   if (chunk !== null) {
 6     process.stdout.write('data ' + chunk);
 7   }
 8 });
 9 
10 process.stdin.on('end', function() {
11   process.stdout.write('end');
12 });

    做爲一個流,process.stdin 也能夠用於「老」模式,那是爲了兼容使用 v0.10 以前的 node 所寫的代碼。更多信息參看流兼容性
    在「老」模式下標準輸入流默認是暫停的,因此必須調用 process.stdin.resume() 來從從裏面讀取。並且須要注意調用 process.stdin.resume() 自己會將流選擇爲「老」模式。
    若是你正在啓動一個新項目,你應該選擇更現代的「新」流模式而不是「老」的。
數組

process.argv

    一個包含命令行參數的數組。第一個元素爲 'node',第二個元素爲 JavaScript 文件名。剩下的參數爲附加的命令行參數。
1 // print process.argv
2 process.argv.forEach(function(val, index, array) {
3   console.log(index + ': ' + val);
4 });

    輸出將會是:安全

$ node process-2.js one two=three four
0: node
1: /User/mjr/work/node/process-2.js
2: one
3: two=three
4: four

process.execPath

    這是啓動進程的可執行程序的絕對路徑。
     例子:
/usr/local/bin/node

process.execArgv

    這是啓動進程的可執行程序的 node 特殊的命令行參數集。這些選項不會在 process.argv 出現,且不會包括 node 可執行程序,腳本名,或任何在腳本名後的選項。當爲了使用父進程一樣的執行環境建立子進程,這些參數是有用的。
    例子:
$ node --harmony script.js --version

    process.execArgv 的結果:架構

['--harmony']

   process.argv 的結果:
dom

['/usr/local/bin/node', 'script.js', '--version']

process.abort()

    這會致使 node 發射一個 abort。這回引發 node 退出並建立一個核心文件。異步

process.chdir(directory)

    改變進程的當前工做目錄或若是失敗則拋出一個異常。
1 console.log('Starting directory: ' + process.cwd());
2 try {
3   process.chdir('/tmp');
4   console.log('New directory: ' + process.cwd());
5 }
6 catch (err) {
7   console.log('chdir: ' + err);
8 }

process.cwd()

   返回進程的當前工做目錄。
1 console.log('Current directory: ' + process.cwd());

process.env

    一個包含用戶環境的對象。參看 environ(7)。 

process.exit([code])

    使用指定的 code 中止進程。若是省略,使用「成功」碼 0 退出。
    使用一個「失敗」碼退出:
1 process.exit(1);

    執行 node 的 shell 將看到1做爲退出碼。

process.getgid()

    注意:這個函數只在 POSIX 平臺下可用(也就是 Windows 不能使用)
    獲取進程的組標識。(參看 getgid(2)。)這是數字組 id,不是組名。
1 if (process.gid) {
2   console.log('Current gid: ' + process.getgid());
3 }

process.setgid(id)

    注意:這個函數只在 POSIX 平臺下可用(也就是 Windows 不能使用)
    設置進程的組標識。(參看 setgid(2)。)接收一個數值 ID 或一個組名字符串。若是組名指定,本函數阻塞直到將它解析爲一個數值 ID。
 1 if (process.getgid && process.setgid) {
 2   console.log('Current gid: ' + process.getgid());
 3   try {
 4     process.setgid(501);
 5     console.log('New gid: ' + process.getgid());
 6   }
 7   catch (err) {
 8     console.log('Failed to set gid: ' + err);
 9   }
10 }

process.getuid()

    注意:這個函數只在 POSIX 平臺下可用(也就是 Windows 不能使用)
    獲取進程的用戶標識。(參看 getuid(2)。)這是一個數值用戶 id,不是用戶名。
1 if (process.getuid) {
2   console.log('Current uid: ' + process.getuid());
3 }

process.setuid(id)

    注意:這個函數只在 POSIX 平臺下可用(也就是 Windows 不能使用)
    設置進程的用戶標識。(參看 setuid(2)。)接收一個數值 ID 或一個用戶名字符串。若是用戶名指定,本函數阻塞直到將它解析爲一個數值 ID。
 1 if (process.getuid && porcess.setuid) {
 2   console.log('Current uid: ' + process.getuid());
 3   try {
 4     process.setuid(501);
 5     console.log('New uid: ' + process.getuid());
 6   }
 7   catch (err) {
 8     console.log('Failed to set uid: ' + err);
 9   }
10 }

process.getgroups()

    注意:這個函數只在 POSIX 平臺下可用(也就是 Windows 不能使用)
    返回一個保存補充組 ID 的數組。若是有效組 ID 被包含在內 POSIX 無論它讓它未指定,但 node.js 確保它老是。
// 說明:不熟悉 POSIX,真心看不懂。

process.setgroups(groups)

    注意:這個函數只在 POSIX 平臺下可用(也就是 Windows 不能使用)
    設置補充組 ID。這是一個特權選項,意味着你須要爲 root 用戶或擁有 CAP_SETGID 的能力。
    列表能夠包含組 ID,組名,或兩者都包含。

process.initgroups(user, extra_group)

    注意:這個函數只在 POSIX 平臺下可用(也就是 Windows 不能使用)
    使用用戶名所在的全部組,讀取/etc/group且初始化組可訪問列表。這是一個特權選項,意味着你須要爲 root 用戶或擁有 CAP_SETGID 的能力。
    user 是一個用戶名或用戶 ID。extra_group 是一個組名或組 ID。
    當註銷權限時須要注意。例子:
1 console.log(process.getgroups());         // [ 0 ]
2 process.initgroups('bnoordhuis', 1000);   // switch user
3 console.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]
4 process.setgid(1000);                     // drop root gid
5 console.log(process.getgroups());         // [ 27, 30, 40, 1000 ]
// 說明:不熟悉 POSIX,真心看不懂。

process.version

    一個表示 NODE_VERSION 的編譯進來的屬性。
1 console.log('Version: ' + process.version);

process.versions

   一個表示 node 和它的依賴的版本字符串屬性。
1 console.log(process.versions);

    將打印以下輸出:

{ http_parser: '1.0',
  node: '0.10.4',
  v8: '3.14.5.8',
  ares: '1.9.0-DEV',
  uv: '0.10.3',
  zlib: '1.2.3',
  modules: '11',
  openssl: '1.0.1e' }

process.config

    一個包含咱們用來編譯當前 node 可執行文件的配置選項的 JavaScript representation 的對象(//注:這裏看不懂啥是 representation ,看英文吧)。這和運行 ./configure 腳本生成的「config.gypi"是同樣的。
    可能的輸出例子以下:
{ target_defaults:
  { cflags: [],
    default_configuration: 'Release',
    defines: [],
    include_dirs: [],
    libraries: [] },
  variables:
  { host_arch: 'x64',
    node_install_npm: 'true',
    node_prefix: '',
    node_shared_cares: 'false',
    node_shared_http_parser: 'false',
    node_shared_libuv: 'false',
    node_shared_v8: 'false',
    node_shared_zlib: 'false',
    node_use_dtrace: 'false',
    node_use_openssl: 'true',
    node_shared_openssl: 'false',
    strict_aliasing: 'true',
    target_arch: 'x64',
    v8_use_snapshot: 'true' } }

process.kill(pid, [signal])

    發送一個信號給進程 pidpid 爲進程 id,signal 爲描述發送的信號的字符串。信號名爲形如 'SIGINT 或 'SIGHUP' 的字符串。若是省略,信號默認爲 'SIGTERM'。更多信息參看 Signal Events 和 kill(2)。
    若是目標進程不存在將拋出一個異常,且做爲特例,信號 0 能夠用來測試進程是否存在。
    注意只是由於這個函數的名字是 process.kill,它實際上只是一個信號發送者,如同系統調用 kill。信號發送後能夠作其它事情而不只僅殺死目標進程。
    發送信號給本身的例子:
 1 process.on('SIGHUP', function() {
 2   console.log('Got SIGHUP signal.');
 3 });
 4 
 5 setTimeout(function() {
 6   console.log('Existing.');
 7   process.exit(0);
 8 }, 100);
 9 
10 process.kill(process.pid, 'SIGHUP');

    注意:當 Node.js 接收到 SIGUSR1 它會啓動調試器,參看 Signal Events

process.pid 

    進程的 PID。
1 console.log('This process is pid ' + process.pid);

process.title

    用來設置在 ’ps' 中的顯示什麼的 getter/setter。
    看成爲 getter 使用時,最大長度由系統指定,有多是很短的。
    在 Linux 和 OS X 下,它受限於名字二進制大小加上命令行參數長度,由於它覆蓋了參數內存。
    v0.8 經過也覆蓋環境內存容許更長的進程標題字符串,但那有潛在的不安全性/在某些狀況下會混亂(不只是模糊不清)。

process.arch

    你運行在什麼處理器架構上:'arm''ia32',或 'x64'
1 console.log('This processor architecture is ' + process.arch);

process.platform

    你運行在什麼平臺上:'darwin''freebsd''linux''sunos',或 'win32'
1 console.log('This platform is ' + process.platform);

process.memoryUsage()

    返回一個描述 Node 進程內存使用的對象,單位是字節。
1 var util = require('util');
2 
3 console.log(util.inspect(process.memoryUsage()));

    這將打印:

{ rss: 4935680,
  heapTotal: 1826816,
  heapUsed: 650472 }

    heapTotalheapUsed 表示 V8 的內存使用。

process.nextTick(callback)

    在事件循環的下一次調用這個回調函數。這僅是 setTimeout(fn, 0) 的別名,它更有效率。典型地它在任何其餘的 I/O 事件以前運行,但有一些例外。參看下面的 process.maxTickDepth
1 process.nextTick(function() {
2   console.log('nextTick callback');
3 });

    在開發 API 時若你想給用戶機會去在對象被建立以後但在任何 I/O 發生以前分配事件監聽器,這個函數是很重要的。

 1 function MyThing(options) {
 2   this.setupOptions(options);
 3 
 4   process.nextTick(function() {
 5     this.startDoingStuff();
 6   }.bind(this));
 7 }
 8 
 9 var thing = new MyThing();
10 thing.getReadyForStuff();
11 
12 // thing.startDoingStuff() gets called now, not before.

   保證 API 是100%同步的或100%異步的是很是重要的。考慮下面的例子:

1 // WARNING! DO NOT USE! BAD UNSAFE HAZARD!
2 function maybeSync(arg, cb) {
3   if (arg) {
4     cb();
5     return;
6   }
7 
8   fs.stat('file', cb);
9 }

    這個 API 是冒險的。若是你執行下面:

1 maybeSync(true, function() {
2   foo();
3 });
4 bar();

    那麼不清楚到底 foo() 仍是 bar() 先被執行。
    這個方法會更好:

1 function definitelyAsync(arg, cb) {
2   if (arg) {
3     process.nextTick(cb);
4     return;
5   }
6 
7   fs.stat('file', cb);
8 }

process.maxTickDepth

    ● 數字類型 默認值 = 1000
    傳遞給 process.nextTick 的回調函數一般會在當前的執行結束後才被調用,所以近似於儘快地同步調用一個函數。不進行任何檢驗,這將有可能餓死時間循環,阻止任何的 I/O 調用發起。
    考慮這樣的代碼:
1 process.nextTick(function foo() {
2   process.nextTick(foo);
3 });

    爲了不 Node 被一系列遞歸 nextTick 無限循環鎖阻塞,它會延遲來讓一些 I/O 每隔一段時間被執行。
    process.maxTickDepth 的值是 nextTick 調用 nextTick 回調函數的最大深度,以在容許其餘形式的 I/O 發起前進行評估。

process.umask([mask])

    設置或讀取進程的文件模式的建立掩碼。子進程從父進程繼承掩碼。若是 mask 參數給出則返回就是掩碼,不然返回當前的掩碼。
1 var oldmask, newmask = 0644;
2 
3 oldmask = process.umask(newmask);
4 console.log('Changed umask from: ' + oldmask.toString(8) +
5   ' to ' + newmask.tostring(8));

process.uptime()

    Node 已經運行的秒數。

process.hrtime()

    返回 [秒,納秒] 的元組數組形式的當前高精度真實時間。它相對於過去的任意時間。它不是跟一天中的某個時間有關,所以不會受制於時鐘偏移。主要的用途是測量某間隔間的程序執行。
    你能夠傳遞以前的調用結果給 process.hrtime() 來得到一個差別值,對基準和測量間隔頗有用:
 1 var time = process.hrtime();
 2 // [ 1800216, 25 ]
 3 
 4 setTimeout(function() {
 5   var diff = process.hrtime(time);
 6   // [ 1, 552]
 7 
 8   console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
 9   // benchmark took 1000000527 nanaseconds
10 }, 1000);
相關文章
相關標籤/搜索