nodeJS之進程process對象

来源:http://www.cnblogs.com/xiaohuochai/archive/2017/06/02/6926080.html
-Advertisement-
Play Games

[1]概述 [2]屬性 [3]方法 [4]輸入輸出流 [5]事件 ...


前面的話

  process對象是一個全局對象,在任何地方都能訪問到它,通過這個對象提供的屬性和方法,使我們可以對當前運行的程式的進程進行訪問和控制。本文將詳細介紹process對象

 

概述

  process是一個全局對象,即global對象的屬性,可以在任何地方直接訪問到它而無需引入額外模塊

console.log(process === global.process);//true
console.log(process);

 

屬性

【process.argv】

  包含命令行參數的數組。第一個元素會是'node',第二個元素將是.js文件的名稱,接下來的參數依次是命令行參數

console.log(process.argv);//[ 'D:\\nodejs\\node.exe', 'D:\\project\\main.js' ]

【process.execArgv】

  啟動進程所需的 node 命令行參數。這些參數不會在 process.argv 里出現,並且不包含 node 執行文件的名字,或者任何在名字之後的參數。這些用來生成子進程,使之擁有和父進程有相同的參數

console.log(process.execArgv);

【process.execPath】

  開啟當前進程的執行文件的絕對路徑

console.log(process.execPath);//D:\nodejs\node.exe

【process.env】

  獲取當前系統環境信息的對象,常規可以用來進一步獲取環境變數、用戶名等系統信息

/*
{ PROCESSOR_ARCHITEW6432: 'AMD64',
  PROCESSOR_LEVEL: '6',
  COMMONPROGRAMW6432: 'C:\\Program Files\\Common Files',
  PROMPT: '$P$G',
  PSMODULEPATH: 'C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules\\',
  APPDATA: 'C:\\Users\\Administrator\\AppData\\Roaming',
  COMPUTERNAME: 'BAI',
  COMSPEC: 'C:\\WINDOWS\\system32\\cmd.exe',
  FPS_BROWSER_APP_PROFILE_STRING: 'Internet Explorer',
  USERPROFILE: 'C:\\Users\\Administrator',
  HOMEDRIVE: 'C:',
  USERNAME: 'Administrator',
  FP_NO_HOST_CHECK: 'NO',
  WINDIR: 'C:\\WINDOWS',
  PROCESSOR_REVISION: '3c03',
  FPS_BROWSER_USER_PROFILE_STRING: 'Default',
  TMP: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp',
  _DFX_INSTALL_UNSIGNED_DRIVER: '1',
  PUBLIC: 'C:\\Users\\Public',
  'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files',
  NUMBER_OF_PROCESSORS: '8',
  SYSTEMROOT: 'C:\\WINDOWS',
  TEMP: 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp',
  PROCESSOR_ARCHITECTURE: 'x86',
  LOCALAPPDATA: 'C:\\Users\\Administrator\\AppData\\Local',
  VISUALSVN_SERVER: 'D:\\soft\\svn1\\',
  COMMONPROGRAMFILES: 'C:\\Program Files (x86)\\Common Files',
  NODE_PATH: 'D:\\nodejs\\node_modules',
  ALLUSERSPROFILE: 'C:\\ProgramData',
  HOMEPATH: '\\Users\\Administrator',
  USERDOMAIN: 'BAI',
  WINDOWS_TRACING_LOGFILE: 'C:\\BVTBin\\Tests\\installpackage\\csilogfile.log',
  PROGRAMFILES: 'C:\\Program Files (x86)',
  VBOX_MSI_INSTALL_PATH: 'D:\\soft\\va\\',
  SYSTEMDRIVE: 'C:',
  PATH: 'C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\WIDCOMM\\Bluetooth Software\\;C:\\Program Files\\WIDCOMM\\Bluetooth Software\\syswow64;C:\\Program Files (x86)\\Microsoft SQL Server\\80\\Tools\\Binn\\;d:\\;D:\\nodejs;D:\\nodejs\\;D:\\Git\\cmd;D:\\soft\\svn1\\bin;D:\\soft\\svn2\\bin;C:\\Ruby23\\bin;D:\\soft\\Sublime Text 3\\less.js-windows-master;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;D:\\wamp\\bin\\mysql\\mysql5.6.17\\bin;C:\\Users\\Administrator\\AppData\\Roaming\\npm',
  PROGRAMW6432: 'C:\\Program Files',
  PATHEXT: '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC',
  WINDOWS_TRACING_FLAGS: '3',
  PROCESSOR_IDENTIFIER: 'Intel64 Family 6 Model 60 Stepping 3, GenuineIntel',
  USERDOMAIN_ROAMINGPROFILE: 'BAI',
  LOGONSERVER: '\\\\BAI',
  PROGRAMDATA: 'C:\\ProgramData',
  SESSIONNAME: 'Console',
  'PROGRAMFILES(X86)': 'C:\\Program Files (x86)',
  OS: 'Windows_NT' }
 */
console.log(process.env);
console.log(process.env.USERNAME);//Administrator

【process.version】

  一個暴露編譯時存儲版本信息的內置變數NODE_VERSION的屬性

console.log(process.version);//v6.9.2

【process.versions】

  一個暴露存儲node以及其依賴包版本信息的屬性

/*
{ http_parser: '2.7.0',
  node: '6.9.2',
  v8: '5.1.281.88',
  uv: '1.9.1',
  zlib: '1.2.8',
  ares: '1.10.1-DEV',
  icu: '57.1',
  modules: '48',
  openssl: '1.0.2j' }
 */
console.log(process.versions);

【process.pid】

  當前進程的 PID

setInterval(function(){
    console.log(process.pid);//11204
}, 5000);

【process.arch】

  返回當前CPU的架構('arm'、'ia32' 或者 'x64')

console.log(process.arch);//ia32

【process.platform】

  運行程式所在的平臺系統 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'

console.log(process.platform); //win32

 

方法

【process.cwd】

   返回當前進程的工作目錄

console.log(process.cwd());//D:\project

【process.chdir(directory)】

  改變當前工作進程的目錄,如果操作失敗拋出異常

console.log(process.cwd());//D:\project
try {
  process.chdir('./dist');
  console.log(process.cwd());//D:\project\dist
}
catch (err) {
  console.log('chdir: ' + err);
}

【process.memoryUsage()】

  返回一個對象,它描述了Node進程的記憶體使用情況,其單位是bytes

console.log(process.memoryUsage()); //{ rss: 18894848, heapTotal: 7274496, heapUsed: 3263160 }

 【process.uptime()】

  返回 Node 程式已運行的秒數

console.log(process.uptime());//0.139
var arr = new Array(200000000);
var s = arr.join(',');
console.log(process.uptime());//0.212

【process.hrtime()】

  返回當前的高分辨時間,形式為 [秒,納秒] 的元組數組。它是相對於在過去的任意時間。該值與日期無關,因此不受時鐘漂移的影響。主要用途是可以通過精確的時間間隔,來衡量程式的性能

var t1 = process.hrtime();
var arr = new Array(200000000),
    s = arr.join(',');
var t2 = process.hrtime();
//處理數組共花費了0秒,詳細為64756416納秒
console.log('處理數組共花費了%d秒,詳細為%d納秒', (t2[0] - t1[0]), (t2[1] - t1[1]));

【process.kill(pid, [signal])】

  結束對應某pid的進程併發送一個信號(若沒定義信號值則預設為'SIGTERM')

console.log(process.pid);//19960
process.kill(process.pid, 'SIGTERM');
console.log(process.pid);//''

【process.abort()】

  觸發node的abort事件,退出當前進程

process.abort();
console.log('在輸出這句話之前就退出了');

【process.exit([code])】

  終止當前進程並返回給定的code。如果省略了code,退出時會預設返回成功的狀態碼('success' code) 也就是0

process.exit(); //[Finished in 0.2s]
process.exit(1); //[Finished in 0.2s with exit code 1]

  更多的返回狀態碼可參考下方列表

1 未捕獲的致命異常(Uncaught Fatal Exception) - There was an uncaught exception, and it was not handled by a domain or an uncaughtException event handler.
2 - 未使用(Unused) (reserved by Bash for builtin misuse)
3 解析錯誤(Internal JavaScript Parse Error) - The JavaScript source code internal in Node's bootstrapping process caused a parse error. This is extremely rare, and generally can only happen during development of Node itself.
4 評估失敗(Internal JavaScript Evaluation Failure) - The JavaScript source code internal in Node's bootstrapping process failed to return a function value when evaluated. This is extremely rare, and generally can only happen during development of Node itself.
5 致命錯誤(Fatal Error) - There was a fatal unrecoverable error in V8. Typically a message will be printed to stderr with the prefix FATAL ERROR.
6 未正確的異常處理(Non-function Internal Exception Handler) - There was an uncaught exception, but the internal fatal exception handler function was somehow set to a non-function, and could not be called.
7 異常處理函數運行時失敗(Internal Exception Handler Run-Time Failure) - There was an uncaught exception, and the internal fatal exception handler function itself threw an error while attempting to handle it. This can happen, for example, if a process.on('uncaughtException') or domain.on('error') handler throws an error.
8 - 未使用(Unused). In previous versions of Node, exit code 8 sometimes indicated an uncaught exception.
9 - 無效的參數(Invalid Argument) - Either an unknown option was specified, or an option requiring a value was provided without a value.
10 運行時失敗(Internal JavaScript Run-Time Failure) - The JavaScript source code internal in Node's bootstrapping process threw an error when the bootstrapping function was called. This is extremely rare, and generally can only happen during development of Node itself.
12 無效的調試參數(Invalid Debug Argument) - The --debug and/or --debug-brk options were set, but an invalid port number was chosen.
>128 信號退出(Signal Exits) - If Node receives a fatal signal such as SIGKILL or SIGHUP, then its exit code will be 128 plus the value of the signal code. This is a standard Unix practice, since exit codes are defined to be 7-bit integers, and signal exits set the high-order bit, and then contain the value of the signal code.

【process.exitCode】

  可以自定義退出進程時node shell捕獲到的狀態碼(必須是正常結束進程或者使用process.exit()指令退出)

  [註意]如果指明瞭 process.exit(code) 中退出的錯誤碼 (code),則會覆蓋掉 process.exitCode 的設置

process.exitCode = 4;
process.exit();//[Finished in 0.2s with exit code 4]
process.exitCode = 4;
process.exit(2);//[Finished in 0.2s with exit code 2]

 

輸入輸出流

【process.stdout】

  一個指向標準輸出流(stdout)的可寫的流(Writable Stream)

/*
這是一行數據
這是第二行數據
 */
process.stdout.write('這是一行數據\n這是第二行數據');

【process.stderr】

  一個指向標準錯誤流(stderr)的 可寫的流(Writable Stream)

//輸出一行標準錯誤流,效果跟stdout沒差[Finished in 0.2s]
process.stderr.write('輸出一行標準錯誤流,效果跟stdout沒差');

【process.stdin】

  一個指向標準輸入流(stdin)的可讀流(Readable Stream)。標準輸入流預設是暫停(pause)的,所以必須要調用process.stdin.resume()來恢復(resume)接收

process.stdin.resume();
var a,b;
process.stdout.write('請輸入a的值: ');
process.stdin.on('data',function(data){
    if(a == undefined){
        a = Number(data);
        process.stdout.write('請輸入b的值: ');
    }else{    
        b = Number(data);
        process.stdout.write('結果是: ' + (a+b));
        process.exit();
    }

    
})

 

事件

【事件'exit'】

  當進程將要退出時觸發。這是一個在固定時間檢查模塊狀態(如單元測試)的好時機。需要註意的是 'exit' 的回調結束後,主事件迴圈將不再運行,所以計時器也會失效

/*
1
退出前執行
 */
process.on('exit', function() {
    // 設置一個延遲執行
    setTimeout(function() {
        console.log('主事件迴圈已停止,所以不會執行');
    }, 0);
    console.log('退出前執行');
});
setTimeout(function() {
    console.log('1');
}, 500);

【事件'uncaughtException'】

  捕獲那些沒有try catch的異常錯誤

//捕獲到一個異常
process.on('uncaughtException', function() {
    console.log('捕獲到一個異常');
});
var a = '123';
a.a(); //觸發異常事件
console.log('這句話不會顯示出來');

【事件'SIGINT'】

  捕獲當前進程接收到的信號(如按下了 ctrl + c)

process.on('SIGINT', function() {
    console.log('收到 SIGINT 信號。');
});
console.log('試著按下 ctrl + C');
setTimeout(function() {
    console.log('end');
}, 50000);
 

nextTick

【process.nextTick(callback)】

  該方法算是 process 對象最重要的一個屬性方法了,表示在事件迴圈(EventLoop)的下一次迴圈中調用 callback 回調函數。這不是 setTimeout(fn, 0) 函數的一個簡單別名,因為它的效率高多了。該函數能在任何 I/O 事前之前調用回調函數。如果想要在對象創建之後而I/O操作發生之前執行某些操作,那麼這個函數就十分重要了

  Node.js是單線程的,除了系統IO之外,在它的事件輪詢過程中,同一時間只會處理一個事件。可以把事件輪詢想象成一個大的隊列,在每個時間點上,系統只會處理一個事件。即使電腦有多個CPU核心,也無法同時並行的處理多個事件。但也就是這種特性使得node.js適合處理I/O型的應用。在每個I/O型的應用中,只需要給每一個輸入輸出定義一個回調函數即可,他們會自動加入到事件輪詢的處理隊列里。當I/O操作完成後,這個回調函數會被觸發。然後系統會繼續處理其他的請求

  在這種處理模式下,process.nextTick()的意思就是定義出一個動作,並且讓這個動作在下一個事件輪詢的時間點上執行

function foo() {
    console.error('foo');
}
 
process.nextTick(foo);
console.error('bar');
/*
bar
foo
*/

  也可以使用setTimeout()函數來達到貌似同樣的執行效果

setTimeout(foo, 0);
console.log('bar');

  但在內部的處理機制上,process.nextTick()和setTimeout(fn, 0)是不同的,process.nextTick()不是一個單純的延時,它有更多的特性。更精確的說,process.nextTick()定義的調用會創建一個新的子堆棧。在當前的棧里,可以執行任意多的操作。但一旦調用nextTick,函數就必須返回到父堆棧。然後事件輪詢機制又重新等待處理新的事件,如果發現nextTick的調用,就會創建一個新的棧。

  在下麵的例子里有一個compute(),我們希望這個函數儘可能持續的執行,來進行一些運算密集的任務。但與此同時,我們還希望系統不要被這個函數堵塞住,還需要能響應處理別的事件。這個應用模式就像一個單線程的web服務server。在這裡我們就可以使用process.nextTick()來交叉執行compute()和正常的事件響應

var http = require('http');
function compute() {
    // performs complicated calculations continuously
    process.nextTick(compute);
}
http.createServer(function(req, res) {
     res.writeHead(200, {'Content-Type': 'text/plain'});
     res.end('Hello World');
}).listen(5000, '127.0.0.1');
compute();

  在這種模式下,我們不需要遞歸的調用compute(),只需要在事件迴圈中使用process.nextTick()定義compute()在下一個時間點執行即可。在這個過程中,如果有新的http請求進來,事件迴圈機制會先處理新的請求,然後再調用compute()。反之,如果把compute()放在一個遞歸調用里,那系統就會一直阻塞在compute()里,無法處理新的http請求了

  當然,我們無法通過process.nextTick()來獲得多CPU下並行執行的真正好處,這隻是模擬同一個應用在CPU上分段執行而已

【總結】

  Nodejs的特點是事件驅動,非同步I/O產生的高併發,產生此特點的引擎是事件迴圈,事件被分門別類地歸到對應的事件觀察者上,比如idle觀察者,定時器觀察者,I/O觀察者等等,事件迴圈每次迴圈稱為Tick,每次Tick按照先後順序從事件觀察者中取出事件進行處理

  調用setTimeout()或setInterval()時創建的計時器會被放入定時器觀察者內部的紅黑樹中,每次Tick時,會從該紅黑樹中檢查定時器是否超過定時時間,超過的話,就立即執行對應的回調函數。setTimeout()和setInterval()都是當定時器使用,他們的區別在於後者是重覆觸發,而且由於時間設的過短會造成前一次觸發後的處理剛完成後一次就緊接著觸發

  由於定時器是超時觸發,這會導致觸發精確度降低,比如用setTimeout設定的超時時間是5秒,當事件迴圈在第4秒循到了一個任務,它的執行時間3秒的話,那麼setTimeout的回調函數就會過期2秒執行,這就是造成精度降低的原因。並且由於採用紅黑樹和迭代的方式保存定時器和判斷觸發,較為浪費性能

  使用process.nextTick()所設置的所有回調函數都會放置在數組中,會在下一次Tick時所有的都立即被執行,該操作較為輕量,時間精度高

  setImmediate()設置的回調函數也是在下一次Tick時被調用,其和process.nextTick()的區別在於兩點:

    1、所屬的觀察者被執行的優先順序不一樣,process.nextTick()屬於idle觀察者,setImmediate()屬於check觀察者,idle的優先順序>check

      2、setImmediate()設置的回調函數是放置在一個鏈表中,每次Tick只執行鏈表中的一個回調。這是為了保證每次Tick都能快速地被執行

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分享生產列印系統的項目管理、研發、測試、運維等各方面的經驗。嘗試介紹我們設計新折桂列印平臺系統的思路。拋磚引玉,期望與大家交流。 ================================ ...
  • 1.什麼是介面? 介面是事物最高的概括,從最高層次上設計了事物的形態。本質上是一系列規範,所有實現了介面的類都實現了該規範,從而使得在相容該規範的地方任何一個實現類都適用。 2.什麼是面向介面編程? 需求商品時,不是指定特定的商品,而是指定需求的條件,任何一個符合條件的事物都可以成為合格的商品。具體 ...
  • 1.什麼是功能模塊化 將實現不同功能的代碼分別存放到不同的文件、類、方法中,每一個文件、類、方法都是一個實現單一功能的模塊。 2.為什麼使用模塊化 模塊化的文件、類、方法功能單一,可以相對獨立存在,不僅降低了對其他對象的依賴,而且層次清晰,便於維護。 3.模塊化的具體實現方法 通過增加模塊數目減小單 ...
  • avalon2是一款基於虛擬DOM與屬性劫持的 迷你、 易用、 高性能 的 前端MVVM框架, 擁有超優秀的相容性, 支持移動開發, 後端渲染, WEB Component式組件開發, 無需編譯, 開箱即用。 官網:http://avalonjs.coding.me/ 《Avalon探索之旅》第一講 ...
  • Math.ceil():向上取整 Math.floor():向下取整 Math.round():四捨五入 需要註意的比如:Math.ceil(-1.6) = -1.0; Math.round(-1.5) = -1; Math.round(-1.6) = -2; ...
  • Sticky footer佈局是什麼? 我們所見到的大部分網站頁面,都會把一個頁面分為頭部區塊、內容區塊和頁腳區塊,當頭部區塊和內容區塊內容較少時,頁腳能固定在屏幕的底部,而非隨著文檔流排布。當頁面內容較多時,頁腳能隨著文檔流自動撐開,顯示在頁面的最底部,這就是Sticky footer佈局。 圖示 ...
  • JavaScript的類型 原始類型: number string boolean null undefined 對象類型: Object function Array Date ... 隱式轉換 運算 "37" + 7 = "377" "37" 7 = 30 運算 以下為true: "1.23" ...
  • var result={ "a":{ "x":5, "y":0, "z":0 }, "b":{ "x":0, "y":0, "z":3 }, "c":{ "x":5, "y":0, "z":0 }, ... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...