node ( 5 ) -----process詳解(這個標題不討喜……)

好想吃涼皮發表於2018-04-16

程式

process 物件是一個全域性變數,它提供當前 Node.js 程式的有關資訊,以及控制當前 Node.js 程式。 因為是全域性變數,所以無需使用 require()。在Node.js中每個應用程式都是一個程式類的例項物件。

程式物件屬性

  • execPath 可執行檔案的絕對路徑,如 /usr/local/bin/node
  • version 版本號
  • versions依賴庫的版本號
  • platform 執行平臺。 如 darwin、freebsd、linux、sunos、win32
  • stdin 標準輸入流可讀流,預設暫停狀態
  • stdout 標準輸出可寫流,同步操作
  • argv 屬性值為陣列
  • env 作業系統環境資訊
  • title 視窗標題
  • arch 處理器架構 arm ia32 x64
process.stdin.resume();
process.stdin.on('data',function(chunk){
  process.stdout.write(`程式接收到資料: `+chunk);
});
複製程式碼
process.argv.forEach((val,index,ary)=> console.log(index,val));

複製程式碼

方法

1.memoryUsage 記憶體佔用情況

process.memoryUsage()
複製程式碼
  • rss(resident set size):所有記憶體佔用,包括指令區和堆疊。
  • heapTotal:"堆"佔用的記憶體,包括用到的和沒用到的。
  • heapUsed:用到的堆的部分。
  • external: V8 引擎內部的 C++ 物件佔用的記憶體。

2.nextTick nextTick方法用於將一個函式推遲到程式碼中所書寫的下一個同步方法執行完畢或非同步方法的回撥函式開始執行前呼叫 3. chdir chdir方法用於修改Node.js應用程式中使用的當前工作目錄,使用方式如下

process.chdir(directory);
複製程式碼

4.cwd cwd方法用返回當前目錄,不使用任何引數

console.log(process.cwd());
複製程式碼

5.chdir 改變當前的工作目錄

console.log(`當前目錄: ${process.cwd()}`);
process.chdir('..);
console.log(`上層目錄: ${process.cwd()});
複製程式碼

6.exit 退出執行Node.js應用程式的程式

process.exit(0);
複製程式碼

7.kill

  • SIGINT 程式終止(interrupt)訊號, 在使用者鍵入INTR字元(通常是Ctrl-C)時發出,用於通知前臺程式組終止程式。
  • SIGTERM 程式結束(terminate)訊號, 該訊號可以被阻塞和處理。通常用來要求程式自己正常退出,shell命令kill預設產生這個訊號
  • pid是一個整數,用於指定需要接收訊號的程式ID
  • signal 傳送的訊號,預設為 SIGTERM
process.kill(pid,[signal]);
複製程式碼

8.uptime 返回當前程式的執行時間

process.uptime()

複製程式碼

9.hrtime 測試一個程式碼段的執行時間,返回兩個時間,第一個單位是秒,第二個單位是納秒

let fs = require('fs);
let time = process.hrtime();
let data = fs.readFileSync('index.txt');
let diff = process.hrtime(time);
console.log(`讀檔案操作耗費的%d秒`,diff[0]);
複製程式碼

10.exit

當執行Node.js應用程式程式退出時觸發程式物件的exit事件。可以通過指定事件回撥函式來指定程式退出時所執行的處理。(先退出,後關閉)

process.on('exit',function(){
    console.log('Node.js程式被推出);
});
process.exit();
複製程式碼

11.uncaughtException 當應用程式丟擲一個未被捕獲的異常時觸發程式物件的uncaughtException事件

process.on('uncaughtException',function(err){
  console.log('捕獲到一個未被處理的錯誤:',err);
});
複製程式碼

12.訊號事件

process.stdin.resume();
process.on('SIGINT',function(){
    console.log('接收到SIGINT訊號');
});
複製程式碼

子程式

  • 在Node.js中,只有一個執行緒執行所有操作,如果某個操作需要大量消耗CPU資源的情況下,後續操作都需要等待。
  • 在Node.js中,提供了一個child_process模組,通過它可以開啟多個子程式,在多個子程式之間可以共享記憶體空間,可以通過子程式的互相通訊來實現資訊的交換。

spawn

child_process.spawn(command,[args],[options]);
複製程式碼
  • command 必須指定的引數,指定需要執行的命令
  • args 陣列,存放了所有執行該命令需要的引數
  • options 引數為一個物件,用於指定開啟子程式時使用的選項
    • cwd 子程式的工作目錄
    • env 環境變數
    • detached 如果為true,該子程式魏一個程式組中的領頭程式,當父程式不存在時也可以獨立存在
    • stdio 三個元素的陣列,設定標準輸入/輸出
      • pipe 在父程式和子程式之間建立一個管道,父程式可以通過子程式的stdio[0]訪問子程式的標準輸入,通過stdio[1]訪問標準輸出,stdio[2]訪問錯誤輸出
      • ipc 在父程式和子程式之間建立一個專用與傳遞訊息的IPC通道。可以呼叫子程式的send方法向子程式發訊息,子程式會觸發message事件
      • ignore 指定不為子程式設定檔案描述符。這樣子程式的標準輸入、標準輸出和錯誤輸出被忽略
      • stream 子程式和父程式共享一個終端裝置、檔案、埠或管道
      • 正整數值 和共享一個steam是一樣的
      • null或undefined 在子程式中建立與父程式相連的管道
      • argv 代表的是子程式的引數,是個陣列且第一,二項是固定的,(執行環境,執行檔案) 預設情況下,子程式的stdin,stdout,stderr導向了ChildProcess這個物件的child.stdin,child.stdout,child.stderr流, 案例: spawn
let {spawn} = require('child_process');
let path = require('path');
// process.cwd()
let child = spawn('node',['1.test.js','a','b','c'],{
    cwd:path.join(__dirname,'pro')
    
});

//如果不寫stdio 預設是管道型別
child.stdout.on('data',function(data){
    console.log(data.toString());
});
複製程式碼

1.test.js

process.argv.slice(2).forEach(function(arg){
    process.stdout.write(arg);
})  
複製程式碼

node 執行spawn檔案,結果如下

a
bc
exit
close
複製程式碼

detached

  • 在預設情況下,只有在子程式全部退出後,父程式才能退出。為了讓父程式可以先退出,而讓子程式繼續進行I/O操作,可以在spawn方法中使用options引數,把detached屬性值設定為true
  • 預設情況下父程式會等待所有的子程式退出後才可以退出,使用subprocess.unref方法可以讓父程式不用等待子程式退出就可以直接退出 detached.js
// detach 將主程式關掉,子程式可以自己執行

// unref()

let {spawn} = require('child_process');
let path  = require('path');
let fd = require('fs').openSync('./100.txt','w')
let child = spawn('node',['detach.js'],{
    cwd:path.join(__dirname,'pro'),
    stdio:['ignore',fd,'ignore'],
    detached:true
});
child.unref();
複製程式碼

detached.test.js

// 會自動將這個描述符包裝成可寫流
setInterval(function(){
    process.stdout.write('hello');
},1000);//最後只能在工作管理員中關了程式
複製程式碼

ipc 用send和onmessage通訊 ipc

let {spawn} = require('child_process');
let path = require('path');
let child = spawn('node',['3.ipc.js'],{
    cwd:path.join(__dirname,'pro'),
    stdio:['pipe','pipe','pipe','ipc']
})
// ignore 不要子程式的資料
// pipe 管道建立管道
// null
child.send({name:'李雷'});

child.on('message',function(data){
    console.log(data);//不會自動關閉,會一直跑著
    child.kill(); // 殺死程式
});
複製程式碼

ipc.test.js

process.on('message',function(msg){
    process.send(msg.name+'很帥')
})
複製程式碼

fork

  • 衍生一個新的 Node.js 程式,並通過建立一個 IPC 通訊通道來呼叫一個指定的模組,該通道允許父程式與子程式之間相互傳送資訊
  • fork方法返回一個隱式建立的代表子程式的ChildProcess物件
  • 子程式的輸入/輸出操作執行完畢後,子程式不會自動退出,必須使用process.exit()方法顯式退出
child_process.fork(modulePath,[args],[options]);
複製程式碼
  • args 執行該檔案模組檔案時許喲啊使用的引數
  • options 選項物件
    • cwd 指定子程式當前的工作目錄
    • env 屬性值為一個物件,用於以"鍵名/鍵值"的形式為子程式指定環境變數
    • encoding 屬性值為一個字串,用於指定輸出及標準錯誤輸出資料的編碼格式,預設值為'utf8'
    • silent 屬性值為布林值,當屬性值為false時,子程式和父程式物件共享標準(輸入/輸出),true時不共享

fork.js

let { spawn } = require('child_process');
let path = require('path');

let child = fork('fork.js', ['a', 'b', 'c'], {
    cwd: path.join(__dirname, 'pro'),
    silent: false // 這句話的意思就是 ['ignore','ignore','ignore','ipc']安靜
});
// 預設支援ipc的方式
// 預設的fork [0,1,2,'ipc']
child.send('hello');
複製程式碼

其實fork的實現很簡單

function fork(modulePath, args, options = {}) {
    if (options.silent) {
        options.stdio = ['ignore', 'ignore', 'ignore', 'ipc']
    } else {
        options.stdio = [0, 1, 2, 'ipc']
    }
    return spawn('node', [modulePath, ...args],options)
}
複製程式碼

看看誰點讚了

node ( 5 ) -----process詳解(這個標題不討喜……)

相關文章