一、計算CPU利用率(計算方式與top指令源碼方式相同)
1.計算宿主機的cpu核數
2. 從文件中讀取本身進程的一段時間使用情況,即隔一段時間分別獲取使用情況,通過這段時間的(使用時間)/(總時間),即可得到cpu利用率,代碼如下:
#include "stdlib.h"
#include "stdio.h"
#include "unistd.h"
#include <iostream>
#include <string>
#include <fstream>
typedef struct cpu_usage_info
{
unsigned long cpu_total_usage;
unsigned long system_useage;
}CPU_USAGE_INFO;
typedef struct cpu_sys_info
{
char szName[16];
unsigned long user; // 從系統啓動開始累計到當前時刻,用戶態的CPU時間(單位:jiffies) ,不包含 nice值爲負進程。1jiffies=0.01秒
unsigned long nice; // 從系統啓動開始累計到當前時刻,nice值爲負的進程所佔用的CPU時間(單位:jiffies)
unsigned long system; // 從系統啓動開始累計到當前時刻,核心時間(單位:jiffies)
unsigned long idle; // 從系統啓動開始累計到當前時刻,除硬盤IO等待時間以外其它等待時間(單位:jiffies)
unsigned long iowait; // 從系統啓動開始累計到當前時刻,硬盤IO等待時間(單位:jiffies) ,
unsigned long irq; // 從系統啓動開始累計到當前時刻,硬中斷時間(單位:jiffies)
unsigned long softirq; // 從系統啓動開始累計到當前時刻,軟中斷時間(單位:jiffies)
}CPU_SYS_INFO;
long GetCpuNum()
{
std::fstream fIn("/proc/stat", std::ios::in);
if(false == fIn.is_open())
{
return -1;
}
std::string strLine1;
std::string strLineCpu; // 含有CPU字段的文本
do
{
std::getline(fIn, strLine1);
auto nPos = strLine1.find("cpu");
// 本行文本不包含cpu字段則跳出
if(std::string::npos == nPos)
{
break;
}
else{
// 本行包含cpu字段則保存起來
strLineCpu = strLine1;
}
}
while(!fIn.eof());
if(true == strLineCpu.empty())
{
std::cout << "get cpu num failed." << std::endl;
return -1;
}
else{
auto nPos = strLineCpu.find(" ");
std::string strCpu = strLineCpu.substr(3, nPos-3);
//std::cout << "--------" << strCpu << std::endl;
long lCpuNum = atoi(strCpu.c_str()) + 1;
//std::cout << "CpuNum: " << lCpuNum << std::endl;
return lCpuNum;
}
}
long getCPUInfo(CPU_USAGE_INFO *pstCpuUsageInfo)
{
// 讀取CPU使用時間,單位納秒
char szCpuAcctUsagePath[256] = "/sys/fs/cgroup/cpuacct/cpuacct.usage";
char szBuff[256];
FILE* fd;
fd = fopen(szCpuAcctUsagePath,"r");
if(NULL == fd)
{
printf("open file cpuacct.usage failed.");
return -1;
}
fgets(szBuff, sizeof(szBuff),fd);
sscanf(szBuff,"%lu",&pstCpuUsageInfo->cpu_total_usage);
fclose(fd);
fd = NULL;
// 讀取系統CPU使用時間,單位jiffies(0.01s)
CPU_SYS_INFO stCpuSysInfo;
char szCpuSystemUsagePath[256] = "/proc/stat";
fd = fopen(szCpuSystemUsagePath,"r");
if(NULL == fd)
{
printf("open file stat failed.");
return -1;
}
fgets(szBuff, sizeof(szBuff), fd);
sscanf(szBuff, "%s %lu %lu %lu %lu %lu %lu %lu",
stCpuSysInfo.szName, &stCpuSysInfo.user, &stCpuSysInfo.nice, &stCpuSysInfo.system, &stCpuSysInfo.idle,
&stCpuSysInfo.iowait, &stCpuSysInfo.irq, &stCpuSysInfo.softirq);
pstCpuUsageInfo->system_useage = stCpuSysInfo.user+stCpuSysInfo.nice+stCpuSysInfo.system+
stCpuSysInfo.idle+stCpuSysInfo.iowait+ stCpuSysInfo.irq+ stCpuSysInfo.softirq;
fclose(fd);
return 0;
}
long getCpuRate()
{
CPU_USAGE_INFO stPreCpuUsageInfo;
CPU_USAGE_INFO stCpuUsageInfo;
long lRet = -1;
lRet = getCPUInfo(&stPreCpuUsageInfo);
if(0 != lRet)
{
printf("get PreCpuUsage failed.\n");
return -1;
}
// 等待200ms
usleep(200000);
//sleep(1);
lRet = getCPUInfo(&stCpuUsageInfo);
if(0 != lRet)
{
printf("get CpuUsage failed.\n");
return -1;
}
/* printf("Usage:%lu, %lu;\n", stCpuUsageInfo.cpu_total_usage, stPreCpuUsageInfo.cpu_total_usage);
printf("Sys:%lu,%lu\n", stCpuUsageInfo.system_useage,stPreCpuUsageInfo.system_useage);
printf("cpu delta:%lu\n", (stCpuUsageInfo.cpu_total_usage- stPreCpuUsageInfo.cpu_total_usage));
printf("sys delta:%lu\n", stCpuUsageInfo.system_useage-stPreCpuUsageInfo.system_useage); */
//
float fCpuRate = (float)(stCpuUsageInfo.cpu_total_usage- stPreCpuUsageInfo.cpu_total_usage)/(float)((stCpuUsageInfo.system_useage-stPreCpuUsageInfo.system_useage)*100000);
long lCpuNum = GetCpuNum();
printf("Using Cpu rate:%f\n", fCpuRate*lCpuNum);
return (long)fCpuRate;
//return 0;
}
int main()
{
std::cout << "system Cpu Number: " <<GetCpuNum() << std::endl;
while(true)
{
long lRet = getCpuRate();
sleep(1);
std::cout << std::endl;
}
return 0;
}
如果想獲取本身的使用情況,需要獲取pid,進入對應的文件夾下讀取信息,百度一下就知道;
附送C版本getNum
long GetCpuNum()
{
char szBuff[1024];
char szLine[1024];
char *szCpuNum = NULL;
FILE *fIn = fopen("/proc/stat", "r");
if(NULL == fIn)
{
printf("open /proc/stat failed, error getting cpu num\n");
return -1;
}
while(fgets(szBuff, sizeof(szBuff), fIn) != NULL)
{
printf("%s\n", szBuff);
char *s = strstr(szBuff,"cpu");
if(NULL == s)
{
break;
}
else
{
strncpy(szLine, szBuff, sizeof(szLine)-1);
}
}
if(strlen(szLine) == 0)
{
printf("get cpu line failed\n");
return -1;
}
else
{
printf("\n");
printf("szLine:%s", szLine);
szCpuNum = strtok(szLine, " ");
printf("cpuNum:%d\n", atoi(szCpuNum+3));
return (long)atoi(szCpuNum);
}
}
二、獲取mem使用情況
未完待續