侃侃无极
窗上面的一些值很容易从适当的Win 32 API中获得,我只是在这里列出它们的完整性。然而,另一些则需要从性能数据帮助库(PDH)中获得,这有点“不直观”,需要大量痛苦的尝试和错误才能开始工作。(至少花了我一段时间,也许我只是有点傻.)注意:为了清楚起见,以下代码省略了所有错误检查。检查返回码.!总虚拟内存:#include "windows.h"MEMORYSTATUSEX memInfo;memInfo.dwLength = sizeof(MEMORYSTATUSEX);GlobalMemoryStatusEx(&memInfo);
DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile;注意:这里的名字“TotalPageFile”有点误导。实际上,这个参数给出了“虚拟内存大小”,即交换文件加上已安装RAM的大小。当前使用的虚拟内存:与“总虚拟内存”中的代码相同,然后DWORDLONG virtualMemUsed = memInfo.ullTotalPageFile - memInfo.ullAvailPageFile;当前进程当前使用的虚拟内存:#include "windows.h"#include "psapi.h"PROCESS_MEMORY_COUNTERS_EX pmc;GetProcessMemoryInfo(GetCurrentProcess(),
&pmc, sizeof(pmc));SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;总物理内存(RAM):与“总虚拟内存”中的代码相同,然后DWORDLONG totalPhysMem = memInfo.ullTotalPhys;目前使用的物理内存:Same code as in "Total Virtual Memory" and thenDWORDLONG physMemUsed = memInfo.ullTotalPhys - memInfo.ullAvailPhys;当前进程当前使用的物理内存:与“当前进程当前使用的虚拟内存”中的代码相同,然后SIZE_T physMemUsedByMe = pmc.WorkingSetSize;目前使用的CPU:#include "TCHAR.h"#include "pdh.h"static PDH_HQUERY cpuQuery;static PDH_HCOUNTER cpuTotal;void init(){
PdhOpenQuery(NULL, NULL, &cpuQuery);
// You can also use L"\\Processor(*)\\% Processor Time" and get individual CPU values with
PdhGetFormattedCounterArray()
PdhAddEnglishCounter(cpuQuery, L"\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal);
PdhCollectQueryData(cpuQuery);}double getCurrentValue(){
PDH_FMT_COUNTERVALUE counterVal;
PdhCollectQueryData(cpuQuery);
PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);
return counterVal.doubleValue;}当前进程当前使用的CPU:#include "windows.h"static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;static int numProcessors;static
HANDLE self;void init(){
SYSTEM_INFO sysInfo;
FILETIME ftime, fsys, fuser;
GetSystemInfo(&sysInfo);
numProcessors = sysInfo.dwNumberOfProcessors;
GetSystemTimeAsFileTime(&ftime);
memcpy(&lastCPU, &ftime, sizeof(FILETIME));
self = GetCurrentProcess();
GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);
memcpy(&lastSysCPU, &fsys, sizeof(FILETIME));
memcpy(&lastUserCPU, &fuser, sizeof(FILETIME));}double getCurrentValue(){
FILETIME ftime, fsys, fuser;
ULARGE_INTEGER now, sys, user;
double percent;
GetSystemTimeAsFileTime(&ftime);
memcpy(&now, &ftime, sizeof(FILETIME));
GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);
memcpy(&sys, &fsys, sizeof(FILETIME));
memcpy(&user, &fuser, sizeof(FILETIME));
percent = (sys.QuadPart - lastSysCPU.QuadPart) +
(user.QuadPart - lastUserCPU.QuadPart);
percent /= (now.QuadPart - lastCPU.QuadPart);
percent /= numProcessors;
lastCPU = now;
lastUserCPU = user;
lastSysCPU = sys;
return percent * 100;}linux在linux上,一开始似乎很明显的选择是使用POSIX API,如getrusage()等。我花了一些时间试着让它发挥作用,但却没有得到有意义的价值。当我最终检查内核源代码时,我发现这些API显然还没有在Linux2.6内核中完全实现!最后,我通过合并读取伪文件系统获得了所有的值。/proc和内核调用。总虚拟内存:#include "sys/types.h"#include "sys/sysinfo.h"struct sysinfo memInfo;sysinfo (&memInfo);long long totalVirtualMem
= memInfo.totalram;//Add other values in next statement to avoid int overflow on right hand
side...totalVirtualMem += memInfo.totalswap;totalVirtualMem *= memInfo.mem_unit;当前使用的虚拟内存:与“总虚拟内存”中的代码相同,然后long long virtualMemUsed = memInfo.totalram - memInfo.freeram;//Add other values in next statement to avoid
int overflow on right hand side...virtualMemUsed += memInfo.totalswap - memInfo.freeswap;virtualMemUsed *= memInfo.mem_unit;当前进程当前使用的虚拟内存:#include "stdlib.h"#include "stdio.h"#include "string.h"int parseLine(char* line){
// This assumes that a digit will be found and the line ends in " Kb".
int i = strlen(line);
const char* p = line;
while (*p <'0' || *p > '9') p++;
line[i-3] = '\0';
i = atoi(p);
return i;}int getValue(){ //Note: this value is in KB!
FILE* file = fopen("/proc/self/status", "r");
int result = -1;
char line[128];
while (fgets(line, 128, file) != NULL){
if (strncmp(line, "VmSize:", 7) == 0){
result = parseLine(line);
break;
}
}
fclose(file);
return result;}总物理内存(RAM):与“总虚拟内存”中的代码相同,然后long long totalPhysMem = memInfo.totalram;//Multiply in next statement to avoid int overflow on right hand
side...totalPhysMem *= memInfo.mem_unit;目前使用的物理内存:与“总虚拟内存”中的代码相同,然后long long physMemUsed = memInfo.totalram - memInfo.freeram;//Multiply in next statement to avoid int overflow
on right hand side...physMemUsed *= memInfo.mem_unit;当前进程当前使用的物理内存:在“当前进程当前使用的虚拟内存”中更改getValue()如下:int getValue(){ //Note: this value is in KB!
FILE* file = fopen("/proc/self/status", "r");
int result = -1;
char line[128];
while (fgets(line, 128, file) != NULL){
if (strncmp(line, "VmRSS:", 6) == 0){
result = parseLine(line);
break;
}
}
fclose(file);
return result;}目前使用的CPU:#include "stdlib.h"#include "stdio.h"#include "string.h"static unsigned long long lastTotalUser, lastTotalUserLow,
lastTotalSys, lastTotalIdle;void init(){
FILE* file = fopen("/proc/stat", "r");
fscanf(file, "cpu %llu %llu %llu %llu", &lastTotalUser, &lastTotalUserLow,
&lastTotalSys, &lastTotalIdle);
fclose(file);}double getCurrentValue(){
double percent;
FILE* file;
unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total;
file = fopen("/proc/stat", "r");
fscanf(file, "cpu %llu %llu %llu %llu", &totalUser, &totalUserLow,
&totalSys, &totalIdle);
fclose(file);
if (totalUser < lastTotalUser || totalUserLow < lastTotalUserLow ||
totalSys < lastTotalSys || totalIdle < lastTotalIdle){
//Overflow detection. Just skip this value.
percent = -1.0;
}
else{
total = (totalUser - lastTotalUser) + (totalUserLow - lastTotalUserLow) +
(totalSys - lastTotalSys);
percent = total;
total += (totalIdle - lastTotalIdle);
percent /= total;
percent *= 100;
}
lastTotalUser = totalUser;
lastTotalUserLow = totalUserLow;
lastTotalSys = totalSys;
lastTotalIdle = totalIdle;
return percent;}当前进程当前使用的CPU:#include "stdlib.h"#include "stdio.h"#include "string.h"#include "sys/times.h"#include "sys/vtimes.h"static clock_t lastCPU,
lastSysCPU, lastUserCPU;static int numProcessors;void init(){
FILE* file;
struct tms timeSample;
char line[128];
lastCPU = times(&timeSample);
lastSysCPU = timeSample.tms_stime;
lastUserCPU = timeSample.tms_utime;
file = fopen("/proc/cpuinfo", "r");
numProcessors = 0;
while(fgets(line, 128, file) != NULL){
if (strncmp(line, "processor", 9) == 0) numProcessors++;
}
fclose(file);}double getCurrentValue(){
struct tms timeSample;
clock_t now;
double percent;
now = times(&timeSample);
if (now <= lastCPU || timeSample.tms_stime < lastSysCPU ||
timeSample.tms_utime < lastUserCPU){
//Overflow detection. Just skip this value.
percent = -1.0;
}
else{
percent = (timeSample.tms_stime - lastSysCPU) +
(timeSample.tms_utime - lastUserCPU);
percent /= (now - lastCPU);
percent /= numProcessors;
percent *= 100;
}
lastCPU = now;
lastSysCPU = timeSample.tms_stime;
lastUserCPU = timeSample.tms_utime;
return percent;}Todo:其他平台我假设,除了读取/proc伪文件系统的部分之外,一些Linux代码也适用于unix。也许在unix上,这些部件可以由getrusage()还有类似的功能?如果有Unix技术的人可以编辑这个答案并填写详细信息?!