前言
本腳本僅僅在 linux 上方便使用,請大家注意,先不廢話,上腳本。
代碼
/*
測試程序
while( true ){
a = exports.getProcessCPUUsage( [ 2882, 10388 ], oldProcessTock )
oldProcessTock = a.processTick;
// rate += parseFloat( a.rate );
count++;
if( count % 100000 == 0 ){
console.log( `${count} ${rate}` )
console.log( Date.now() )
count = 0;
rate = 0;
}
}
平均每秒該方法可以操作
21579.628830384117 次
測試平台
Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
*/
var fs = require( 'fs' );
var os = require( 'os' );
var CPUCoreNumbers = os.cpus().length;
var CPUTikHistory = null;
exports.getProcessCPUUsage = ( pid, oldProcessTick, sysTickPerSec ) => {
// let ProcessStat = fs.readFileSync( `/proc/${process.pid}/stat`, 'utf8' );
var ProcessTickSum = 0;
if( Array.isArray( pid ) ){
pid.forEach( p => {
let ProcessStat = fs.readFileSync( `/proc/${p}/stat`, 'utf8' );
let ProcessStatArr = ProcessStat.match( /(\w+)+/g )
if( ProcessStatArr == null ) return null;
ProcessTickSum += parseInt( ProcessStatArr[13] ) + parseInt( ProcessStatArr[14] );
} )
}else{
let ProcessStat = fs.readFileSync( `/proc/${pid}/stat`, 'utf8' );
let ProcessStatArr = ProcessStat.match( /(\w+)+/g )
if( ProcessStatArr == null ) return null;
ProcessTickSum = parseInt( ProcessStatArr[13] ) + parseInt( ProcessStatArr[14] );
}
let TikSum = 0;
if( sysTickPerSec == null ){
let CPUStat = fs.readFileSync( '/proc/stat', 'utf8' );
let MatchLine = CPUStat.match(/(.*)\n/);
if( MatchLine == null ){
console.error( "This function not match this machain, please take care" );
process.exit();
}
let CPULineArr = MatchLine[1].match( /(\w+)+/g );
// console.log( CPULineArr )
if( CPULineArr[0] != 'cpu' ){
console.error( "This function not match this machain, please take care" );
process.exit();
}
CPULineArr.forEach( (num) => {
let i = parseInt( num );
if( isNaN( i ) ) return;
TikSum += parseInt(num);
} )
if( CPUTikHistory == null ){
CPUTikHistory = TikSum;
}
}
if( ( oldProcessTick == null ) || ( oldProcessTick == 0 ) ){
if( sysTickPerSec == null ){
return {
rate: 0.00,
processTick: ProcessTickSum,
sysTick: TikSum,
}
}else{
return {
rate: 0.00,
processTick: ProcessTickSum,
}
}
}
if( sysTickPerSec == null ){
DiffSysTick = TikSum - CPUTikHistory;
CPUTikHistory = TikSum;
if( DiffSysTick == 0 ){
return {
rate: 0,
processTick: ProcessTickSum,
sysTick: TikSum,
}
}
let rate = ( ProcessTickSum - oldProcessTick )*100/DiffSysTick*CPUCoreNumbers
return {
rate: rate.toFixed(2),
processTick: ProcessTickSum,
sysTick: TikSum,
}
}else{
let rate = ( ProcessTickSum - oldProcessTick )*100/sysTickPerSec*CPUCoreNumbers;
return {
rate: rate.toFixed(2),
processTick: ProcessTickSum,
}
}
}
//==============================================================================
// let oldProcessTock = 0;
// setInterval( ()=>{
//
// a = exports.getProcessCPUUsage( [ 2882, 10388 ], oldProcessTock )
// console.log( a );
// oldProcessTock = a.processTick;
//
// }, 1000 );
說明
getProcessCPUUsage 函數接受三個參數,前兩個是必選的,第三個是可選的
pid
代表想查詢程序的 pid, 如果想查詢自己的,可用 proceess.pid 獲取,
如果想合並查詢幾個進程共同的 CPU 占用率,可以用數組包含各個進程的 PID
oldProcessTick
為上一次的進程的 Tick, 如果是第一次則設置為 0,
在運行完本函數后會返回當下指定進程的所有 Tick, 之后可以下一次使用
sysTickPerSec
如果你知道當前系統的一秒內的固定 Tick,你可以從這個參數傳進來,這樣減少該函數的運算所需的資源
如果你不知道,不設置即可,該函數會自動算出兩次調用該函數時間段內的總 Tick
返回有三個參數
rate
CPU 占用率,單位為 xx.xx%, 保留兩位小樹
processTick
指定進程當前 Tick 之和
sysTick
當前系統的總 Tick
當你指定 sysTickPerSec 則無此字段
注意
1. 這里返回的 CPU 占用率是只兩次調用之間的 CPU 占用率,如果你不是嚴格的按照每秒調用一次該函數, CPU 占用率會和 Top 顯示的不一樣。
2. 如果你的硬件平台不只一個 CPU,而且你是按照每秒調用一次,而且你想獲取進程的 CPU 占用率特別高,那么此時此處的 CPU 占用率會超過 100%