代码实现cpu的检测和内存使用情况

找了好多资料,整合如下:

传送门: 1、Linux C++ 获取某一进程的CPU占用率以及内存占用情况

2、C/C++获取Windows系统CPU和内存及硬盘使用情况

3、windows 下检测进程cpu使用率


1、Linux C++ 获取某一进程的CPU占用率以及内存占用情况


最近做监控相关东西的时候,需要获取某一进程CPU以及内存使用情况,就简单的写了一下,代码具体如下:

[cpp] view plain copy
  1. #include <stdio.h>  
  2. #include <unistd.h>  
  3. #include <sys/time.h>  
  4. #include <string.h>  
  5. #include <stdlib.h>  
  6.   
  7. #define VMRSS_LINE 17  
  8. #define VMSIZE_LINE 13  
  9. #define PROCESS_ITEM 14  
  10.   
  11. typedef struct {  
  12.     unsigned long user;  
  13.     unsigned long nice;  
  14.     unsigned long system;  
  15.     unsigned long idle;  
  16. }Total_Cpu_Occupy_t;  
  17.   
  18.   
  19. typedef struct {  
  20.     unsigned int pid;  
  21.     unsigned long utime;  //user time  
  22.     unsigned long stime;  //kernel time  
  23.     unsigned long cutime; //all user time  
  24.         unsigned long cstime; //all dead time  
  25. }Proc_Cpu_Occupy_t;  
  26.   
  27.   
  28. //获取第N项开始的指针  
  29. const char* get_items(const char*buffer ,unsigned int item){  
  30.       
  31.     const char *p =buffer;  
  32.   
  33.     int len = strlen(buffer);  
  34.     int count = 0;  
  35.       
  36.     for (int i=0; i<len;i++){  
  37.         if (' ' == *p){  
  38.             count ++;  
  39.             if(count == item -1){  
  40.                 p++;  
  41.                 break;  
  42.             }  
  43.         }  
  44.         p++;  
  45.     }  
  46.   
  47.     return p;  
  48. }  
  49.   
  50.   
  51. //获取总的CPU时间  
  52. unsigned long get_cpu_total_occupy(){  
  53.       
  54.     FILE *fd;  
  55.     char buff[1024]={0};  
  56.     Total_Cpu_Occupy_t t;  
  57.   
  58.     fd =fopen("/proc/stat","r");  
  59.     if (nullptr == fd){  
  60.         return 0;  
  61.     }  
  62.           
  63.     fgets(buff,sizeof(buff),fd);  
  64.     char name[64]={0};  
  65.     sscanf(buff,"%s %ld %ld %ld %ld",name,&t.user,&t.nice,&t.system,&t.idle);  
  66.     fclose(fd);  
  67.       
  68.     return (t.user + t.nice + t.system + t.idle);  
  69. }  
  70.   
  71.   
  72. //获取进程的CPU时间  
  73. unsigned long get_cpu_proc_occupy(unsigned int pid){  
  74.       
  75.     char file_name[64]={0};  
  76.     Proc_Cpu_Occupy_t t;  
  77.     FILE *fd;  
  78.     char line_buff[1024]={0};  
  79.     sprintf(file_name,"/proc/%d/stat",pid);  
  80.       
  81.     fd = fopen(file_name,"r");  
  82.     if(nullptr == fd){  
  83.         return 0;  
  84.     }  
  85.       
  86.     fgets(line_buff,sizeof(line_buff),fd);  
  87.       
  88.     sscanf(line_buff,"%u",&t.pid);  
  89.     const char *q =get_items(line_buff,PROCESS_ITEM);  
  90.     sscanf(q,"%ld %ld %ld %ld",&t.utime,&t.stime,&t.cutime,&t.cstime);  
  91.     fclose(fd);  
  92.       
  93.     return (t.utime + t.stime + t.cutime + t.cstime);  
  94. }  
  95.   
  96.   
  97. //获取CPU占用率  
  98. float get_proc_cpu(unsigned int pid){  
  99.       
  100.     unsigned long totalcputime1,totalcputime2;  
  101.     unsigned long procputime1,procputime2;  
  102.       
  103.     totalcputime1=get_cpu_total_occupy();  
  104.     procputime1=get_cpu_proc_occupy(pid);  
  105.   
  106.     usleep(200000);  
  107.   
  108.     totalcputime2=get_cpu_total_occupy();  
  109.     procputime2=get_cpu_proc_occupy(pid);  
  110.       
  111.     float pcpu = 0.0;  
  112.     if(0 != totalcputime2-totalcputime1){   
  113.         pcpu=100.0 * (procputime2-procputime1)/(totalcputime2-totalcputime1);  
  114.     }  
  115.       
  116.     return pcpu;  
  117. }  
  118.   
  119.   
  120. //获取进程占用内存  
  121. unsigned int get_proc_mem(unsigned int pid){  
  122.       
  123.     char file_name[64]={0};  
  124.     FILE *fd;  
  125.     char line_buff[512]={0};  
  126.     sprintf(file_name,"/proc/%d/status",pid);  
  127.       
  128.     fd =fopen(file_name,"r");  
  129.     if(nullptr == fd){  
  130.         return 0;  
  131.     }  
  132.       
  133.     char name[64];  
  134.     int vmrss;  
  135.     for (int i=0; i<VMRSS_LINE-1;i++){  
  136.         fgets(line_buff,sizeof(line_buff),fd);  
  137.     }  
  138.       
  139.     fgets(line_buff,sizeof(line_buff),fd);  
  140.     sscanf(line_buff,"%s %d",name,&vmrss);  
  141.     fclose(fd);  
  142.   
  143.     return vmrss;  
  144. }  
  145.   
  146.   
  147. //获取进程占用虚拟内存  
  148. unsigned int get_proc_virtualmem(unsigned int pid){  
  149.       
  150.     char file_name[64]={0};  
  151.     FILE *fd;  
  152.     char line_buff[512]={0};  
  153.     sprintf(file_name,"/proc/%d/status",pid);  
  154.       
  155.     fd =fopen(file_name,"r");  
  156.     if(nullptr == fd){  
  157.         return 0;  
  158.     }  
  159.       
  160.     char name[64];  
  161.     int vmsize;  
  162.     for (int i=0; i<VMSIZE_LINE-1;i++){  
  163.         fgets(line_buff,sizeof(line_buff),fd);  
  164.     }  
  165.       
  166.     fgets(line_buff,sizeof(line_buff),fd);  
  167.     sscanf(line_buff,"%s %d",name,&vmsize);  
  168.     fclose(fd);  
  169.   
  170.     return vmsize;  
  171. }  
  172.   
  173.   
  174. //进程本身  
  175. int get_pid(const char* process_name, const char* user = nullptr)  
  176. {  
  177.     if(user == nullptr){  
  178.         user = getlogin();    
  179.     }  
  180.       
  181.     char cmd[512];  
  182.     if (user){  
  183.         sprintf(cmd, "pgrep %s -u %s", process_name, user);   
  184.     }  
  185.   
  186.     FILE *pstr = popen(cmd,"r");      
  187.       
  188.     if(pstr == nullptr){  
  189.         return 0;     
  190.     }  
  191.   
  192.     char buff[512];  
  193.     ::memset(buff, 0, sizeof(buff));  
  194.     if(NULL == fgets(buff, 512, pstr)){  
  195.         return 0;  
  196.     }  
  197.   
  198.     return atoi(buff);  
  199. }  
  200.   
  201.   
  202. int main(int argc, char *argv[])  
  203. {  
  204.       
  205.     if(argc < 2){  
  206.         printf("Usage:test <process_name> [user]\n");  
  207.         return 1;  
  208.     }  
  209.       
  210.     unsigned int pid=0;  
  211.       
  212.     if(argc > 2){  
  213.         pid = get_pid(argv[1],argv[2]);  
  214.     }  
  215.     else{  
  216.         pid = get_pid(argv[1]);  
  217.     }  
  218.       
  219.     printf("pid=%d\n",pid);  
  220.     printf("pcpu=%f\n",get_proc_cpu(pid));  
  221.     printf("procmem=%d\n",get_proc_mem(pid));  
  222.     printf("virtualmem=%d\n",get_proc_virtualmem(pid));   
  223.     return 0;  
  224. }  

至此对于一个进程主要的物理信息获取完毕。


2、C/C++获取Windows系统CPU和内存及硬盘使用情况


//1.获取Windows系统内存使用率

[cpp] view plain copy
  1. //windows 内存 使用率  
  2. DWORD getWin_MemUsage(){  
  3.     MEMORYSTATUS ms;  
  4.     ::GlobalMemoryStatus(&ms);  
  5.     return ms.dwMemoryLoad;  
  6. }  

//2.获取windowsCPU使用率

[cpp] view plain copy
  1. __int64 CompareFileTime(FILETIME time1, FILETIME time2)  
  2. {  
  3.     __int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;  
  4.     __int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;  
  5.   
  6.     return (b - a);  
  7. }  
  8. //WIN CPU使用情况  
  9. void getWin_CpuUsage(){  
  10.     HANDLE hEvent;  
  11.     BOOL res;  
  12.     FILETIME preidleTime;  
  13.     FILETIME prekernelTime;  
  14.     FILETIME preuserTime;  
  15.     FILETIME idleTime;  
  16.     FILETIME kernelTime;  
  17.     FILETIME userTime;  
  18.   
  19.     res = GetSystemTimes(&idleTime, &kernelTime, &userTime);  
  20.     preidleTime = idleTime;  
  21.     prekernelTime = kernelTime;  
  22.     preuserTime = userTime;  
  23.   
  24.     hEvent = CreateEventA(NULL, FALSE, FALSE, NULL); // 初始值为 nonsignaled ,并且每次触发后自动设置为nonsignaled  
  25.   
  26.     while (true){  
  27.         WaitForSingleObject(hEvent, 1000);  
  28.         res = GetSystemTimes(&idleTime, &kernelTime, &userTime);  
  29.   
  30.         __int64 idle = CompareFileTime(preidleTime, idleTime);  
  31.         __int64 kernel = CompareFileTime(prekernelTime, kernelTime);  
  32.         __int64 user = CompareFileTime(preuserTime, userTime);  
  33.   
  34.         __int64 cpu = (kernel + user - idle) * 100 / (kernel + user);  
  35.         __int64 cpuidle = (idle)* 100 / (kernel + user);  
  36.         cout << "CPU利用率:" << cpu << "%" << " CPU空闲率:" << cpuidle << "%" << endl;  
  37.   
  38.         preidleTime = idleTime;  
  39.         prekernelTime = kernelTime;  
  40.         preuserTime = userTime;  
  41.     }  
  42. }  
[cpp] view plain copy
  1. //获取 WIN 硬盘使用情况  
  2. int getWin_DiskUsage(){  
  3.     int DiskCount = 0;  
  4.     DWORD DiskInfo = GetLogicalDrives();  
  5.     //利用GetLogicalDrives()函数可以获取系统中逻辑驱动器的数量,函数返回的是一个32位无符号整型数据。    
  6.     while (DiskInfo)//通过循环操作查看每一位数据是否为1,如果为1则磁盘为真,如果为0则磁盘不存在。    
  7.     {  
  8.         if (DiskInfo & 1)//通过位运算的逻辑与操作,判断是否为1    
  9.         {  
  10.             ++DiskCount;  
  11.         }  
  12.         DiskInfo = DiskInfo >> 1;//通过位运算的右移操作保证每循环一次所检查的位置向右移动一位。    
  13.         //DiskInfo = DiskInfo/2;    
  14.     }  
  15.     cout << "Logical Disk Number:" << DiskCount << endl;  
  16.     //-----------------------------------------------------------------------------------------  
  17.     int DSLength = GetLogicalDriveStrings(0, NULL);  
  18.     //通过GetLogicalDriveStrings()函数获取所有驱动器字符串信息长度。    
  19.     char* DStr = new char[DSLength];//用获取的长度在堆区创建一个c风格的字符串数组    
  20.     GetLogicalDriveStrings(DSLength, (LPTSTR)DStr);  
  21.     //通过GetLogicalDriveStrings将字符串信息复制到堆区数组中,其中保存了所有驱动器的信息。    
  22.   
  23.     int DType;  
  24.     int si = 0;  
  25.     BOOL fResult;  
  26.     unsigned _int64 i64FreeBytesToCaller;  
  27.     unsigned _int64 i64TotalBytes;  
  28.     unsigned _int64 i64FreeBytes;  
  29.   
  30.     for (int i = 0; i<DSLength / 4; ++i)//为了显示每个驱动器的状态,则通过循环输出实现,由于DStr内部保存的数据是A:\NULLB:\NULLC:\NULL,这样的信息,所以DSLength/4可以获得具体大循环范围    
  31.     {  
  32.         char dir[3] = { DStr[si], ':''\\' };  
  33.         cout << dir;  
  34.         DType = GetDriveType(DStr + i * 4);  
  35.         //GetDriveType函数,可以获取驱动器类型,参数为驱动器的根目录    
  36.         if (DType == DRIVE_FIXED)  
  37.         {  
  38.             cout << "Hard Disk";  
  39.         }  
  40.         else if (DType == DRIVE_CDROM)  
  41.         {  
  42.             cout << "CD-ROM";  
  43.         }  
  44.         else if (DType == DRIVE_REMOVABLE)  
  45.         {  
  46.             cout << "Removable Disk";  
  47.         }  
  48.         else if (DType == DRIVE_REMOTE)  
  49.         {  
  50.             cout << "Network Disk";  
  51.         }  
  52.         else if (DType == DRIVE_RAMDISK)  
  53.         {  
  54.             cout << "Virtual RAM Disk";  
  55.         }  
  56.         else if (DType == DRIVE_UNKNOWN)  
  57.         {  
  58.             cout << "Unknown Device";  
  59.         }  
  60.   
  61.         fResult = GetDiskFreeSpaceEx(  
  62.             dir,  
  63.             (PULARGE_INTEGER)&i64FreeBytesToCaller,  
  64.             (PULARGE_INTEGER)&i64TotalBytes,  
  65.             (PULARGE_INTEGER)&i64FreeBytes);  
  66.         //GetDiskFreeSpaceEx函数,可以获取驱动器磁盘的空间状态,函数返回的是个BOOL类型数据    
  67.         if (fResult)//通过返回的BOOL数据判断驱动器是否在工作状态    
  68.         {  
  69.             cout << " totalspace:" << (float)i64TotalBytes / 1024 / 1024 << " MB";//磁盘总容量    
  70.             cout << " freespace:" << (float)i64FreeBytesToCaller / 1024 / 1024 << " MB";//磁盘剩余空间    
  71.         }  
  72.         else  
  73.         {  
  74.             cout << " 设备未准备好";  
  75.         }  
  76.         cout << endl;  
  77.         si += 4;  
  78.     }  
  79.     return 0;  
  80. }  

//main函数

[cpp] view plain copy
  1. int main( int argc, char **argv )  
  2. {  
  3.     //+++======================获取windows 内存使用率==================+++//  
  4.     DWORD dwValue = getWin_MemUsage();  
  5.     printf("内存使用率为 %d %% \n",dwValue);  
  6.     //+++======================获取Windows CPU使用率====================+++//  
  7.     //getWin_CpuUsage();  
  8.     //+++======================获取Windows 硬盘使用====================+++//  
  9.     getWin_DiskUsage();  
  10.         return 0;  
  11. }  

3、windows 下检测进程cpu使用率


以下内容主要来自http://www.sizeof.cn/html/2010/365.html ,对其中的一些细节进行了调整。
最近在项目中需要监测某个进程的CPU使用率,原本以为是一个很简单的需求,想用Windows上的性能计数器来进行计算的,但是经过尝试之后,发现Windows性能计数器算出来的值根本不正确,不耐经过互联网的搜索,终于发现了以下计算方法,总的测试,发现结果还是比较精准的。

其实Windows的进程使用率计算出来的在一段很短的时间内,计算某进程使用CPU的时间,除以所有进程使用CPU的时间,即为该进程的CPU使用率。具体代码如下:

#include <stdafx.h>

[cpp] view plain copy
  1. #include <stdio.h>    
  2. #include <Windows.h>  
  3. #include <iostream>  
  4.   
  5. using namespace std;  
  6.   
  7. typedef long long           int64_t;  
  8. typedef unsigned long long  uint64_t;  
  9.   
  10. /// 时间转换  
  11. static uint64_t file_time_2_utc(const FILETIME* ftime)  
  12. {  
  13.     LARGE_INTEGER li;  
  14.   
  15.     li.LowPart = ftime->dwLowDateTime;  
  16.     li.HighPart = ftime->dwHighDateTime;  
  17.     return li.QuadPart;  
  18. }  
  19.   
  20. /// 获得CPU的核数  
  21. static int get_processor_number()  
  22. {  
  23.     SYSTEM_INFO info;  
  24.     GetSystemInfo(&info);  
  25.     return (int)info.dwNumberOfProcessors;  
  26. }  
  27.   
  28. int get_cpu_usage(int pid)  
  29. {    
  30.     //cpu数量  
  31.     static int processor_count_ = -1;  
  32.     //上一次的时间  
  33.     static int64_t last_time_ = 0;  
  34.     static int64_t last_system_time_ = 0;  
  35.   
  36.     FILETIME now;  
  37.     FILETIME creation_time;  
  38.     FILETIME exit_time;  
  39.     FILETIME kernel_time;  
  40.     FILETIME user_time;  
  41.     int64_t system_time;  
  42.     int64_t time;  
  43.     int64_t system_time_delta;  
  44.     int64_t time_delta;  
  45.   
  46.     int cpu = -1;  
  47.   
  48.     if(processor_count_ == -1)  
  49.     {  
  50.         processor_count_ = get_processor_number();  
  51.     }  
  52.   
  53.     GetSystemTimeAsFileTime(&now);  
  54.   
  55.     HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);  
  56.     if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time))  
  57.     {  
  58.         return -1;  
  59.     }  
  60.     system_time = (file_time_2_utc(&kernel_time) + file_time_2_utc(&user_time))   
  61.         / processor_count_;    
  62.     time = file_time_2_utc(&now);  
  63.   
  64.     if ((last_system_time_ == 0) || (last_time_ == 0))  
  65.     {  
  66.         last_system_time_ = system_time;  
  67.         last_time_ = time;  
  68.         return get_cpu_usage(pid);  
  69.     }  
  70.   
  71.     system_time_delta = system_time - last_system_time_;  
  72.     time_delta = time - last_time_;  
  73.   
  74.     if (time_delta == 0)  
  75.         return get_cpu_usage(pid);  
  76.   
  77.     cpu = (int)((system_time_delta * 100 + time_delta / 2) / time_delta);  
  78.     last_system_time_ = system_time;  
  79.     last_time_ = time;  
  80.     return cpu;  
  81. }  
  82.   
  83. int main()     
  84. {    
  85.     int cpu;  
  86.     int process_id;  
  87.     // 参数为进程id  
  88.     cin>>process_id;  
  89.   
  90.     while(1)     
  91.     {    
  92.         cpu = get_cpu_usage(process_id);  
  93.         printf("CPU使用率: %d%%\n",cpu);  
  94.   
  95.         Sleep(1000);  
  96.     }     
  97.     return 0;  
  98. }  

致谢!



展开阅读全文

没有更多推荐了,返回首页