前言
本脚本仅仅在 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%