新聞中心
進程
本節(jié)介紹node.js的process(過程)對象,它提供有關當前Node.js過程的信息和控制。

十余年的石首網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。營銷型網(wǎng)站建設的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調(diào)整石首建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“石首網(wǎng)站設計”,“石首網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
process是全局對象,能夠在任意位置對其進行訪問,而無需使用require(),是EventEmitter的實例。
退出狀態(tài)碼
當不需要處理新的異步的操作時,Node正常情況下退出時會返回狀態(tài)碼0。下面提供了一些表示其他狀態(tài)的狀態(tài)碼:
1未捕獲的致命異常-Uncaught Fatal Exception - 有未捕獲異常,并且沒有被域或uncaughtException處理函數(shù)處理。2- Unused (保留)3JavaScript解析錯誤-Internal JavaScript Parse Error - JavaScript的源碼啟動 Node 進程時引起解析錯誤。非常罕見,僅會在開發(fā)Node時才會有。4JavaScript評估失敗-Internal JavaScript Evaluation Failure - JavaScript的源碼啟動Node進程,評估時返回函數(shù)失敗。非常罕見,僅會在開發(fā) Node時才會有。5致命錯誤-Fatal Error - V8里致命的不可恢復的錯誤。通常會打印到stderr,內(nèi)容為:FATAL ERROR6Non-function異常處理-Non-function Internal Exception Handler - 未捕獲異常,內(nèi)部異常處理函數(shù)不知為何設置為on-function,并且不能被調(diào)用。7異常處理函數(shù)運行時失敗-Internal Exception Handler Run-Time Failure - 未捕獲的異常, 并且異常處理函數(shù)處理時自己拋出了異常。例如,如果process.on('uncaughtException')或domain.on('error')拋出了異常。8- Unused保留。 之前版本的Node, 狀態(tài)碼8有時表示未捕獲異常。9- 參數(shù)非法-Invalid Argument - 可能是給了未知的參數(shù),或者給的參數(shù)沒有值。10運行時失敗-Internal JavaScript Run-Time Failure - JavaScript的源碼啟動 Node 進程時拋出錯誤,非常罕見,僅會在開發(fā) Node 時才會有。12無效的Debug參數(shù)-Invalid Debug Argument - 設置了參數(shù)--debug或--debug-brk,但是選擇了錯誤端口。>128信號退出-Signal Exits - 如果Node接收到致命信號,比如SIGKILL或SIGHUP,那么退出代碼就是128加信號代碼。這是標準的Unix做法,退出信號代碼放在高位。
事件: 'exit'
當進程準備退出時觸發(fā)。此時已經(jīng)沒有辦法阻止從事件循環(huán)中推出。因此,你必須在處理函數(shù)中執(zhí)行同步操作。這是一個在固定事件檢查模塊狀態(tài)(比如單元測試)的好時機?;卣{(diào)函數(shù)有一個參數(shù),它是進程的退出代碼。
監(jiān)聽exit事件的例子:
process.on('exit', function(code) {
// do *NOT* do this
setTimeout(function() {
console.log('This will not run');
}, 0);
console.log('About to exit with code:', code);
});
事件: 'beforeExit'
當node清空事件循環(huán),并且沒有其他安排時觸發(fā)這個事件。通常來說,當沒有進程安排時node退出,但是'beforeExit'的監(jiān)聽器可以異步調(diào)用,這樣node就會繼續(xù)執(zhí)行。
'beforeExit'并不是明確退出的條件,process.exit()或異常捕獲才是,所以不要把它當做'exit'事件。除非你想安排更多的工作。
事件: 'uncaughtException'
當一個異常冒泡回到事件循環(huán),觸發(fā)這個事件。如果給異常添加了監(jiān)視器,默認的操作(打印堆棧跟蹤信息并退出)就不會發(fā)生。
監(jiān)聽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是非常簡略的異常處理機制。
盡量不要使用它,而應該用domains 。如果你用了,每次未處理異常后,重啟你的程序。
不要使用node.js里諸如On Error Resume Next這樣操作。每個未處理的異常意味著你的程序,和你的node.js擴展程序,一個未知狀態(tài)。盲目的恢復意味著任何事情都可能發(fā)生
你在升級的系統(tǒng)時拉掉了電源線,然后恢復了??赡?0次里有9次沒有問題,但是第10次,你的系統(tǒng)可能就會掛掉。
Signal 事件
當進程接收到信號時就觸發(fā)。信號列表詳見標準的POSIX信號名,如SIGINT、SIGUSR1等。
監(jiān)聽SIGINT的例子:
// Start reading from stdin so we don't exit.
process.stdin.resume();
process.on('SIGINT', function() {
console.log('Got SIGINT. Press Control-D to exit.');
});在大多數(shù)終端程序里,發(fā)送SIGINT信號的簡單方法是按下信號Control-C。
注意:
SIGUSR1node.js 接收這個信號開啟調(diào)試模式。可以安裝一個監(jiān)聽器,但開始時不會中斷調(diào)試。SIGTERM和SIGINT在非Windows系統(tǒng)里,有默認的處理函數(shù),退出(伴隨退出代碼128 + 信號碼)前,重置退出模式。如果這些信號有監(jiān)視器,默認的行為將會被移除。SIGPIPE默認情況下忽略,可以加監(jiān)聽器。SIGHUP當Windowns控制臺關閉的時候生成,其他平臺的類似條件,參見signal(7)??梢蕴砑颖O(jiān)聽者,Windows平臺上10秒后會無條件退出。在非Windows平臺上,SIGHUP的默認操作是終止node,但是一旦添加了監(jiān)聽器,默認動作將會被移除。SIGTERMWindows不支持,可以被監(jiān)聽。SIGINT所有的終端都支持,通常由CTRL+C生成(可能需要配置)。當終端原始模式啟用后不會再生成。SIGBREAKWindows里,按下CTRL+BREAK會發(fā)送。非Windows平臺,可以被監(jiān)聽,但是不能發(fā)送或生成。SIGWINCH- 當控制臺被重設大小時發(fā)送。Windows系統(tǒng)里,僅會在控制臺上輸入內(nèi)容時,光標移動,或者可讀的tty在原始模式上使用。SIGKILL不能有監(jiān)視器,在所有平臺上無條件關閉node。SIGSTOP不能有監(jiān)視器。
Windows不支持發(fā)送信號,但是node提供了很多process.kill()和child_process.kill()的模擬:
- 發(fā)送Sending信號
0可以查找運行中得進程 - 發(fā)送
SIGINT,SIGTERM和SIGKILL會引起目標進程無條件退出。
process.stdout
一個Writable Stream執(zhí)向stdout(fd1).
例如:console.log的定義:
console.log = function(d) {
process.stdout.write(d + '\n');
};process.stderr和process.stdout和 node 里的其他流不同,他們不會被關閉(end()將會被拋出),它們不會觸發(fā)finish事件,并且寫是阻塞的。
- 引用指向常規(guī)文件或TTY文件描述符時,是阻塞的。
- 引用指向pipe管道時:
- 在Linux/Unix里阻塞.
- 在Windows像其他流一樣,不被阻塞
檢查Node是否運行在TTY上下文中,從process.stderr,process.stdout或process.stdin里讀取isTTY屬性。
$ 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更多信息參見the tty docs。
process.stderr
一個指向stderr (fd2)的可寫流。
process.stderr和process.stdout和node里的其他流不同,他們不會被關閉(end()將會被拋出),它們不會觸發(fā)finish事件,并且寫是阻塞的。
- 引用指向常規(guī)文件或TTY文件描述符時,是阻塞的。
- 引用指向pipe管道時:
- 在Linux/Unix里阻塞
- 在Windows像其他流一樣,不被阻塞
process.stdin
一個指向stdin (fd0)的可讀流。
以下例子:打開標準輸入流,并監(jiān)聽兩個事件:
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() {
var chunk = process.stdin.read();
if (chunk !== null) {
process.stdout.write('data: ' + chunk);
}
});
process.stdin.on('end', function() {
process.stdout.write('end');
});process.stdin可以工作在老模式里,和v0.10之前版本的node代碼兼容。
更多信息參見Stream compatibility.
在老的流模式里,stdin流默認暫停,必須調(diào)用process.stdin.resume()讀取??梢哉{(diào)用process.stdin.resume()切換到老的模式。
如果開始一個新的工程,最好選擇新的流,而不是用老的流。
process.argv
包含命令行參數(shù)的數(shù)組。第一個元素是'node',第二個參數(shù)是JavaScript文件的名字,第三個參數(shù)是任意的命令行參數(shù)。
// print process.argv
process.argv.forEach(function(val, index, array) {
console.log(index + ': ' + val);
});將會生成:
$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four
process.execPath
開啟當前進程的執(zhí)行文件的絕對路徑。
例子:
/usr/local/bin/node
process.execArgv
啟動進程所需的 node 命令行參數(shù)。這些參數(shù)不會在process.argv里出現(xiàn),并且不包含node執(zhí)行文件的名字,或者任何在名字之后的參數(shù)。這些用來生成子進程,使之擁有和父進程有相同的參數(shù)。
例子:
$ node --harmony script.js --versionprocess.execArgv 的參數(shù):
['--harmony']process.argv 的參數(shù):
['/usr/local/bin/node', 'script.js', '--version']
process.abort()
這將導致node觸發(fā)abort事件。會讓node退出并生成一個核心文件。
process.chdir(directory)
改變當前工作進程的目錄,如果操作失敗拋出異常。
console.log('Starting directory: ' + process.cwd());
try {
process.chdir('/tmp');
console.log('New directory: ' + process.cwd());
}
catch (err) {
console.log('chdir: ' + err);
}
process.cwd()
返回當前進程的工作目錄:
console.log('Current directory: ' + process.cwd());
process.env
包含用戶環(huán)境的對象,參見environ(7).
這個對象的例子:
{ TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node' }你可以寫入這個對象,但是不會改變當前運行的進程。以下的命令不會成功:
node -e 'process.env.foo = "bar"' && echo $foo這個會成功:
process.env.foo = 'bar';
console.log(process.env.foo);
process.exit([code])
使用指定的code結束進程。如果忽略,將會使用code 0
使用失敗的代碼退出:
process.exit(1);Shell將會看到退出代碼為1.
process.exitCode
進程退出時的代碼,如果進程優(yōu)雅的退出,或者通過process.exit()退出,不需要指定退出碼。
設定process.exit(code)將會重寫之前設置的process.exitCode。
process.getgid()
注意:這個函數(shù)僅在POSIX平臺上可用(例如,非Windows和Android)。
獲取進程的群組標識(參見getgid(2))。獲取到得時群組的數(shù)字id,而不是名字。
if (process.getgid) {
console.log('Current gid: ' + process.getgid());
}
process.setgid(id)
注意:這個函數(shù)僅在POSIX平臺上可用(例如,非Windows 和 Android)。
設置進程的群組標識(參見setgid(2))??梢越邮諗?shù)字ID或者群組名。如果指定了群組名,會阻塞等待解析為數(shù)字ID 。
if (process.getgid && process.setgid) {
console.log('Current gid: ' + process.getgid());
try {
process.setgid(501);
console.log('New gid: ' + process.getgid());
}
catch (err) {
console.log('Failed to set gid: ' + err);
}
}
process.getuid()
注意:這個函數(shù)僅在POSIX平臺上可用(例如,非Windows和Android)。
獲取進程的用戶標識(參見getuid(2))。這是數(shù)字的用戶id,不是用戶名:
if (process.getuid) {
console.log('Current uid: ' + process.getuid());
}
process.setuid(id)
注意:這個函數(shù)僅在POSIX平臺上可用(例如,非Windows和Android)。
設置進程的用戶標識(參見setuid(2))。接收數(shù)字ID或字符串名字。果指定了群組名,會阻塞等待解析為數(shù)字ID。
if (process.getuid && process.setuid) {
console.log('Current uid: ' + process.getuid());
try {
process.setuid(501);
console.log('New uid: ' + process.getuid());
}
catch (err) {
console.log('Failed to set uid: ' + err);
}
}
process.getgroups()
注意:這個函數(shù)僅在POSIX平臺上可用(例如,非Windows和Android)。
返回進程的群組iD數(shù)組。POSIX系統(tǒng)沒有保證一定有,但是node.js保證有。
process.setgroups(groups)
注意:這個函數(shù)僅在POSIX平臺上可用(例如,非Windows和Android)。
設置進程的群組ID。這是授權操作,所有你需要有root權限,或者有CAP_SETGID能力。
列表可以包含群組IDs,群組名,或者兩者都有。
process.initgroups(user, extra_group)
注意:這個函數(shù)僅在POSIX平臺上可用(例如,非Windows和Android)。
讀取/etc/group ,并初始化群組訪問列表,使用成員所在的所有群組。這是授權操作,所有你需要有root權限,或者有CAP_SETGID能力。
user是用戶名或者用戶ID,extra_group是群組名或群組ID。
當你在注銷權限 (dropping privileges) 的時候需要注意. 例子:
console.log(process.getgroups()); // [ 0 ]
process.initgroups('bnoordhuis', 1000); // switch user
console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ]
process.setgid(1000); // drop root gid
console.log(process.getgroups()); // [ 27, 30, 46, 1000 ]
process.version
一個編譯屬性,包含NODE_VERSION。
console.log('Version: ' + process.version);
process.versions
一個屬性,包含了node的版本和依賴。
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執(zhí)行文件的javascript配置選項的對象。它與運行./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])
發(fā)送信號給進程。pid是進程id,并且signal是發(fā)送的信號的字符串描述。信號名是字符串,比如'SIGINT'或'SIGHUP'。如果忽略,信號會是'SIGTERM'。更多信息參見Signal 事件和kill(2) .
如果進程沒有退出,會拋出錯誤。信號0可以用來測試進程是否存在。
注意,雖然這個這個函數(shù)名叫process.kill,它真的僅是信號發(fā)射器,就像kill系統(tǒng)調(diào)用。信號發(fā)射可以做其他事情,不僅是殺死目標進程。
例子, 給自己發(fā)信號:
process.on('SIGHUP', function() {
console.log('Got SIGHUP signal.');
});
setTimeout(function() {
console.log('Exiting.');
process.exit(0);
}, 100);
process.kill(process.pid, 'SIGHUP');注意:當Node.js接收到SIGUSR1信號,它會開啟debugger調(diào)試模式, 參見Signal Events.
process.pid
當前進程的PID:
console.log('This process is pid ' + process.pid);
process.title
獲取/設置(Getter/setter) 'ps'中顯示的進程名。
使用setter時,字符串的長度由系統(tǒng)指定,可能會很短。
在Linux和OS X上,它受限于名稱的長度加上命令行參數(shù)的長度,因為它會覆蓋參數(shù)內(nèi)存(argv memory)。
v0.8版本允許更長的進程標題字符串,也支持覆蓋環(huán)境內(nèi)存,但是存在潛在的不安全和混亂(很難說清楚)。
process.arch
當前CPU的架構:'arm'、'ia32'或者'x64'。
console.log('This processor architecture is ' + process.arch);
process.platform
運行程序所在的平臺系統(tǒng)'darwin','freebsd','linux','sunos'或者'win32'
console.log('This platform is ' + process.platform);
process.memoryUsage()
返回一個對象,描述了Node進程所用的內(nèi)存狀況,單位為字節(jié)。
var util = require('util');
console.log(util.inspect(process.memoryUsage()));將會生成:
{ rss: 4935680,
heapTotal: 1826816,
heapUsed: 650472 }heapTotal和heapUsed指V8的內(nèi)存使用情況。
process.nextTick(callback)
callback{Function}
一旦當前事件循環(huán)結束,調(diào)用回到函數(shù)。
這不是setTimeout(fn, 0)的簡單別名,這個效率更高。在任何附加I/O事件在子隊列事件循環(huán)中觸發(fā)前,它就會運行。
console.log('start');
process.nextTick(function() {
console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback在對象構造后,在I/O事件發(fā)生前,你又想改變附加事件處理函數(shù)時,這個非常有用。
function MyThing(options) {
this.setupOptions(options);
process.nextTick(function() {
this.startDoingStuff();
}.bind(this));
}
var thing = new MyThing();
thing.getReadyForStuff();
// thing.startDoingStuff() gets called now, not before.要保證你的函數(shù)一定是100%同步執(zhí)行,或者100%異步執(zhí)行。例子:
// WARNING! DO NOT USE! BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
if (arg) {
cb();
return;
}
fs.stat('file', cb);
}這個API非常危險. 如果你這么做:
maybeSync(true, function() {
foo();
});
bar();不清楚foo()或bar()哪個先執(zhí)行。
更好的方法:
function definitelyAsync(arg, cb) {
if (arg) {
process.nextTick(cb);
return;
}
fs.stat('file', cb);
}注意:nextTick隊列會在完全執(zhí)行完畢之后才調(diào)用I/O操作。因此,遞歸設置nextTick的回調(diào)就像一個while(true);循環(huán)一樣,將會阻止任何I/O操作的發(fā)生。
process.umask([mask])
設置或讀取進程文件的掩碼。子進程從父進程繼承掩碼。如果mask參數(shù)有效,返回舊的掩碼。否則,返回當前掩碼。
var oldmask, newmask = 0022;
oldmask = process.umask(newmask);
console.log('Changed umask from: ' + oldmask.toString(8) +
' to ' + newmask.toString(8));
process.uptime()
返回Node已經(jīng)運行的秒數(shù)。
process.hrtime()
返回當前進程的高分辨時間,形式為[seconds, nanoseconds]數(shù)組。它是相對于過去的任意事件。該值與日期無關,因此不受時鐘漂移的影響。主要用途是可以通過精確的時間間隔,來衡量程序的性能。
你可以將之前的結果傳遞給當前的process.hrtime(),會返回兩者間的時間差,用來基準和測量時間間隔。
var time = process.hrtime();
// [ 1800216, 25 ]
setTimeout(function() {
var diff = process.hrtime(time);
// [ 1, 552 ]
console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
// benchmark took 1000000527 nanoseconds
}, 1000);
process.mainModule
require.main的備選方法。不同點,如果主模塊在運行時改變,require.main可能會繼續(xù)返回老的模塊。可以認為,這兩者引用了同一個模塊。
該process.mainModule屬性提供了一種替代的檢索方式require.main。不同之處在于,如果主模塊在運行時發(fā)生更改,require.main可能仍會引用發(fā)生更改之前所需模塊中的原始主模塊。通常,假設這兩個參照相同的模塊是安全的。
和require.main一樣, 如果沒有入口腳本,將會返回undefined。
本文名稱:創(chuàng)新互聯(lián)Node.js教程:Node.js進程
網(wǎng)站網(wǎng)址:http://www.5511xx.com/article/cceejji.html


咨詢
建站咨詢
