如何确定一个进程内部的CPU和内存消耗?

我曾经从运行的应用程序中确定以下性能参数:

  • 可用虚拟内存总量
  • 当前使用的虚拟内存
  • 我的进程当前使用的虚拟内存

  • 可用RAM总量
  • 目前使用的RAM
  • 目前我的进程使用的RAM

  • 当前使用的CPU百分比
  • 当前由我的进程使用的CPU

代码必须在Windows和Linux上运行。 尽pipe这似乎是一个标准任务,但在手册(WIN32 API,GNU文档)以及Internet上find必要的信息花了我好几天,因为关于这个主题的信息太多不完整/不正确/过时在那里发现。

为了避免别人经历同样的麻烦,我认为把所有分散的信息加上我在这里试验和发现的错误都集中在一个地方是个好主意。

视窗

上面的一些值很容易从适当的WIN32 API中获得,我只是在这里列出它们的完整性。 其他的则需要从绩效数据助手库(PDH)中获得,这个数据库有点“不直观”,需要经历很多痛苦的尝试和错误才能开始工作。 (至less我花了一段时间,也许我只是有点愚蠢…)

注意:为清楚起见,以下代码中省略了所有错误检查。 检查返回代码…!

  • 总虚拟内存:

    #include "windows.h" MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile; 

    注意:名称“TotalPageFile”在这里有点误导。 实际上这个参数给出了“虚拟内存大小”,它是交换文件的大小加上安装的RAM。

  • 目前使用的虚拟内存:

    与“Total Virtual Memory”中的代码相同

     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):

    与“Total Virtual Memory”中的代码相同

     DWORDLONG totalPhysMem = memInfo.ullTotalPhys; 
  • 目前使用的物理内存:

     Same code as in "Total Virtual Memory" and then DWORDLONG 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上,首先看起来很明显的select是使用像getrusage()等POSIX API。我花了一些时间试图让这个工作,但从来没有得到有意义的价值。 当我终于自己检查了内核源代码后,发现显然这些API在Linux kernel 2.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; 
  • 目前使用的虚拟内存:

    与“Total Virtual Memory”中的代码相同

     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):

    与“Total Virtual Memory”中的代码相同

     long long totalPhysMem = memInfo.totalram; //Multiply in next statement to avoid int overflow on right hand side... totalPhysMem *= memInfo.mem_unit; 
  • 目前使用的物理内存:

    与“Total Virtual Memory”中的代码相同

     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知识的人可以编辑这个答案并填写细节?!

Mac OS X

我希望能为Mac OS Xfind类似的信息。 既然不在这里,我就出去自己挖了。 这是我发现的一些事情。 如果有人有任何其他的build议,我很乐意听到他们。

总虚拟内存

这个在Mac OS X上很棘手,因为它不使用预设的交换分区或像Linux这样的文件。 以下是苹果公司的文档:

注意:与大多数基于Unix的操作系统不同,Mac OS X不使用预分配的虚拟内存交换分区。 而是使用机器引导分区上的所有可用空间。

因此,如果您想知道还有多less虚拟内存可用,则需要获取根分区的大小。 你可以这样做:

 struct statfs stats; if (0 == statfs("/", &stats)) { myFreeSwap = (uint64_t)stats.f_bsize * stats.f_bfree; } 

当前使用的虚拟总数

使用“vm.swapusage”键调用systcl提供了有关交换使用情况的有趣信息:

 sysctl -n vm.swapusage vm.swapusage: total = 3072.00M used = 2511.78M free = 560.22M (encrypted) 

不是说,如果需要更多的交换,在这里显示的交换使用总量可以改变,如上面的部分所述。 所以这个总额实际上是现在的掉期总额。 在C ++中,这个数据可以这样查询:

 xsw_usage vmusage = {0}; size_t size = sizeof(vmusage); if( sysctlbyname("vm.swapusage", &vmusage, &size, NULL, 0)!=0 ) { perror( "unable to get swap usage by calling sysctlbyname(\"vm.swapusage\",...)" ); } 

请注意,在sysctl.h中声明的“xsw_usage”似乎没有logging,我怀疑有一个更便携的方式来访问这些值。

我的进程当前使用的虚拟内存

您可以使用task_info函数获取有关当前进程的统计信息。 这包括您的stream程的当前常驻大小和当前虚拟大小。

 #include<mach/mach.h> struct task_basic_info t_info; mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; if (KERN_SUCCESS != task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count)) { return -1; } // resident size is in t_info.resident_size; // virtual size is in t_info.virtual_size; 

可用RAM总量

系统中可用的物理RAM的数量可以使用sysctl系统函数,如下所示:

 #include <sys/types.h> #include <sys/sysctl.h> ... int mib[2]; int64_t physical_memory; mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; length = sizeof(int64_t); sysctl(mib, 2, &physical_memory, &length, NULL, 0); 

目前使用的RAM

您可以从host_statistics系统函数获取一般内存统计信息。

 #include <mach/vm_statistics.h> #include <mach/mach_types.h> #include <mach/mach_init.h> #include <mach/mach_host.h> int main(int argc, const char * argv[]) { vm_size_t page_size; mach_port_t mach_port; mach_msg_type_number_t count; vm_statistics64_data_t vm_stats; mach_port = mach_host_self(); count = sizeof(vm_stats) / sizeof(natural_t); if (KERN_SUCCESS == host_page_size(mach_port, &page_size) && KERN_SUCCESS == host_statistics64(mach_port, HOST_VM_INFO, (host_info64_t)&vm_stats, &count)) { long long free_memory = (int64_t)vm_stats.free_count * (int64_t)page_size; long long used_memory = ((int64_t)vm_stats.active_count + (int64_t)vm_stats.inactive_count + (int64_t)vm_stats.wire_count) * (int64_t)page_size; printf("free memory: %lld\nused memory: %lld\n", free_memory, used_memory); } return 0; } 

有一点需要注意的是在Mac OS X中有五种types的内存页面,如下所示:

  1. 有线网页已locking,无法换出
  2. 加载到物理内存中的活动页面将相对难于交换
  3. 被加载到内存中的非活动页面,但最近没有被使用过,甚至根本不需要。 这些是交换的潜在候选人。 这个内存可能需要刷新。
  4. caching的页面,如何caching,可能很容易被重用。 caching的内存可能不需要刷新。 仍然可以重新激活caching的页面
  5. 免费页面,完全免费,可以使用。

值得注意的是,仅仅因为Mac OS X有时可能显示非常less的实际可用内存,可能并不能很好地指示在短时间内准备使用多less内存。

目前我的进程使用的RAM

请参阅上面的“我的进程当前使用的虚拟内存”。 相同的代码适用。

Linux的

在Linux中,这些信息在/ proc文件系统中可用。 我不是所使用的文本文件格式的忠实粉丝,因为每个Linux发行版似乎至less定制了一个重要的文件。 快速查看“ps”的来源显示了这个混乱。

但是,在这里可以find您要查找的信息:

/ proc / meminfo包含您所寻求的大部分系统信息。 这里看起来像我的系统; 我想你对MemTotalMemFreeSwapTotalSwapFree感兴趣

 Anderson cxc # more /proc/meminfo MemTotal: 4083948 kB MemFree: 2198520 kB Buffers: 82080 kB Cached: 1141460 kB SwapCached: 0 kB Active: 1137960 kB Inactive: 608588 kB HighTotal: 3276672 kB HighFree: 1607744 kB LowTotal: 807276 kB LowFree: 590776 kB SwapTotal: 2096440 kB SwapFree: 2096440 kB Dirty: 32 kB Writeback: 0 kB AnonPages: 523252 kB Mapped: 93560 kB Slab: 52880 kB SReclaimable: 24652 kB SUnreclaim: 28228 kB PageTables: 2284 kB NFS_Unstable: 0 kB Bounce: 0 kB CommitLimit: 4138412 kB Committed_AS: 1845072 kB VmallocTotal: 118776 kB VmallocUsed: 3964 kB VmallocChunk: 112860 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 Hugepagesize: 2048 kB 

为了CPU利用率,你必须做一些工作。 Linux在系统启动后使整个CPU利用率可用; 这可能不是你感兴趣的。如果你想知道最近一秒或10秒的CPU利用率,那么你需要查询信息并自己计算。

这些信息可以在/ proc / stat中find ,在http://www.linuxhowtos.org/System/procstat.htm中有详细的logging 。 这里是我的4芯盒子上的样子:

 Anderson cxc # more /proc/stat cpu 2329889 0 2364567 1063530460 9034 9463 96111 0 cpu0 572526 0 636532 265864398 2928 1621 6899 0 cpu1 590441 0 531079 265949732 4763 351 8522 0 cpu2 562983 0 645163 265796890 682 7490 71650 0 cpu3 603938 0 551790 265919440 660 0 9040 0 intr 37124247 ctxt 50795173133 btime 1218807985 processes 116889 procs_running 1 procs_blocked 0 

首先,您需要确定系统中有多less个CPU(或处理器或处理内核)可用。 为此,请计算'cpuN'条目的数量,其中N从0开始并递增。 不要把“cpu”这一行,这是cpuN行的组合。 在我的例子中,你可以看到cpu0到cpu3,共有4个处理器。 从现在开始,你可以忽略cpu0..cpu3,只关注'cpu'行。

接下来,您需要知道这些行中的第四个数字是空闲时间的度量,因此“cpu”行上的第四个数字是自启动以来所有处理器的总空闲时间。 这个时间是在Linux的“jiffies”中测得的,每秒1/100。

但是你不关心总空闲时间, 你关心一段时间的空闲时间,例如最后一秒。 计算一下,你需要读取这个文件两次,相隔1秒。然后你可以做一个线的第四个值的差异。 例如,如果你拿一个样本,得到:

 cpu 2330047 0 2365006 1063853632 9035 9463 96114 0 

然后等一秒钟,你会得到这个样本:

 cpu 2330047 0 2365007 1063854028 9035 9463 96114 0 

减去两个数字,得到396的差异,这意味着你的CPU在最后1.00秒内已经空闲了3.96秒。 诀窍当然是,你需要除以处理器的数量。 3.96 / 4 = 0.99,有空闲的百分比; 99%空闲,1%忙碌。

在我的代码中,我有一个360个条目的环形缓冲区,我每秒钟读这个文件。 这可以让我快速计算CPU使用率1秒,10秒等等,一直到1小时。

对于特定于进程的信息,您必须查看/ proc / pid ; 如果你不关心你的pid,你可以看看/ proc / self。

你的进程使用的CPU在/ proc / self / stat中可用。 这是一个奇怪的文件,由单一行组成; 例如:

 19340 (whatever) S 19115 19115 3084 34816 19115 4202752 118200 607 0 0 770 384 2 7 20 0 77 0 266764385 692477952 105074 4294967295 134512640 146462952 321468364 8 3214683328 4294960144 0 2147221247 268439552 1276 4294967295 0 0 17 0 0 0 0 

这里的重要数据是第13和第14个标记(这里是0和770)。 第13个标记是进程在用户模式下执行的jiffies的数量,第14个是进程在内核模式下执行的jiffies的数量。 把两者加在一起,你就可以得到CPU的总利用率。

同样,您将不得不定期对这个文件进行采样,并计算diff,以便确定进程的CPU使用率。

编辑:记住当你计算你的进程的CPU利用率时,你必须考虑到1)进程中的线程数量,2)系统中的处理器数量。 例如,如果您的单线程进程只使用了25%的CPU,那么可能是好的还是坏的。 擅长单处理器系统,但在4处理器系统上不好; 这意味着您的进程不断运行,并使用100%的CPU周期。

对于特定于进程的内存信息,你可以看看/ proc / self / status,它看起来像这样:

 Name: whatever State: S (sleeping) Tgid: 19340 Pid: 19340 PPid: 19115 TracerPid: 0 Uid: 0 0 0 0 Gid: 0 0 0 0 FDSize: 256 Groups: 0 1 2 3 4 6 10 11 20 26 27 VmPeak: 676252 kB VmSize: 651352 kB VmLck: 0 kB VmHWM: 420300 kB VmRSS: 420296 kB VmData: 581028 kB VmStk: 112 kB VmExe: 11672 kB VmLib: 76608 kB VmPTE: 1244 kB Threads: 77 SigQ: 0/36864 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: fffffffe7ffbfeff SigIgn: 0000000010001000 SigCgt: 20000001800004fc CapInh: 0000000000000000 CapPrm: 00000000ffffffff CapEff: 00000000fffffeff Cpus_allowed: 0f Mems_allowed: 1 voluntary_ctxt_switches: 6518 nonvoluntary_ctxt_switches: 6598 

以'Vm'开始的条目是有趣的:

  • VmPeak是进程使用的最大虚拟内存空间,以kB(1024字节)为单位。
  • VmSize是进程使用的当前虚拟内存空间,以kB为单位。 在我的例子中,它是相当大的:651,352 kB或大约636兆字节。
  • VmRss是映射到进程地址空间或其驻留集大小的内存量。 这是显着更小(420,296 kB,或大约410兆字节)。 区别在于:我的程序通过mmap()映射了636 MB,但只访问了410 MB,因此只有410 MB的页面被分配给它。

我不确定的唯一项目是我的进程当前使用的Swapspace 。 我不知道这是否可用。

在Windows中,您可以通过代码获取cpu使用情况:

 #include <windows.h> #include <stdio.h> //------------------------------------------------------------------------------------------------------------------ // Prototype(s)... //------------------------------------------------------------------------------------------------------------------ CHAR cpuusage(void); //----------------------------------------------------- typedef BOOL ( __stdcall * pfnGetSystemTimes)( LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime ); static pfnGetSystemTimes s_pfnGetSystemTimes = NULL; static HMODULE s_hKernel = NULL; //----------------------------------------------------- void GetSystemTimesAddress() { if( s_hKernel == NULL ) { s_hKernel = LoadLibrary( L"Kernel32.dll" ); if( s_hKernel != NULL ) { s_pfnGetSystemTimes = (pfnGetSystemTimes)GetProcAddress( s_hKernel, "GetSystemTimes" ); if( s_pfnGetSystemTimes == NULL ) { FreeLibrary( s_hKernel ); s_hKernel = NULL; } } } } //---------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------- // cpuusage(void) // ============== // Return a CHAR value in the range 0 - 100 representing actual CPU usage in percent. //---------------------------------------------------------------------------------------------------------------- CHAR cpuusage() { FILETIME ft_sys_idle; FILETIME ft_sys_kernel; FILETIME ft_sys_user; ULARGE_INTEGER ul_sys_idle; ULARGE_INTEGER ul_sys_kernel; ULARGE_INTEGER ul_sys_user; static ULARGE_INTEGER ul_sys_idle_old; static ULARGE_INTEGER ul_sys_kernel_old; static ULARGE_INTEGER ul_sys_user_old; CHAR usage = 0; // we cannot directly use GetSystemTimes on C language /* add this line :: pfnGetSystemTimes */ s_pfnGetSystemTimes(&ft_sys_idle, /* System idle time */ &ft_sys_kernel, /* system kernel time */ &ft_sys_user); /* System user time */ CopyMemory(&ul_sys_idle , &ft_sys_idle , sizeof(FILETIME)); // Could been optimized away... CopyMemory(&ul_sys_kernel, &ft_sys_kernel, sizeof(FILETIME)); // Could been optimized away... CopyMemory(&ul_sys_user , &ft_sys_user , sizeof(FILETIME)); // Could been optimized away... usage = ( ( ( ( (ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart)+ (ul_sys_user.QuadPart - ul_sys_user_old.QuadPart) ) - (ul_sys_idle.QuadPart-ul_sys_idle_old.QuadPart) ) * (100) ) / ( (ul_sys_kernel.QuadPart - ul_sys_kernel_old.QuadPart)+ (ul_sys_user.QuadPart - ul_sys_user_old.QuadPart) ) ); ul_sys_idle_old.QuadPart = ul_sys_idle.QuadPart; ul_sys_user_old.QuadPart = ul_sys_user.QuadPart; ul_sys_kernel_old.QuadPart = ul_sys_kernel.QuadPart; return usage; } //------------------------------------------------------------------------------------------------------------------ // Entry point //------------------------------------------------------------------------------------------------------------------ int main(void) { int n; GetSystemTimesAddress(); for(n=0;n<20;n++) { printf("CPU Usage: %3d%%\r",cpuusage()); Sleep(2000); } printf("\n"); return 0; } 

Linux的

读取内存和加载数字的便携方式是sysinfo调用

用法

  #include <sys/sysinfo.h> int sysinfo(struct sysinfo *info); 

描述

  Until Linux 2.3.16, sysinfo() used to return information in the following structure: struct sysinfo { long uptime; /* Seconds since boot */ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ unsigned long totalram; /* Total usable main memory size */ unsigned long freeram; /* Available memory size */ unsigned long sharedram; /* Amount of shared memory */ unsigned long bufferram; /* Memory used by buffers */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ unsigned short procs; /* Number of current processes */ char _f[22]; /* Pads structure to 64 bytes */ }; and the sizes were given in bytes. Since Linux 2.3.23 (i386), 2.3.48 (all architectures) the structure is: struct sysinfo { long uptime; /* Seconds since boot */ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */ unsigned long totalram; /* Total usable main memory size */ unsigned long freeram; /* Available memory size */ unsigned long sharedram; /* Amount of shared memory */ unsigned long bufferram; /* Memory used by buffers */ unsigned long totalswap; /* Total swap space size */ unsigned long freeswap; /* swap space still available */ unsigned short procs; /* Number of current processes */ unsigned long totalhigh; /* Total high memory size */ unsigned long freehigh; /* Available high memory size */ unsigned int mem_unit; /* Memory unit size in bytes */ char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */ }; and the sizes are given as multiples of mem_unit bytes. 

QNX

由于这就像一个“代码维基”,我想添加一些来自QNX知识库的代码(注意:这不是我的工作,但我检查了它,它在我的系统上工作正常):

如何获取CPU使用率: http : //www.qnx.com/support/knowledgebase.html?id=50130000000P9b5

 #include <atomic.h> #include <libc.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/iofunc.h> #include <sys/neutrino.h> #include <sys/resmgr.h> #include <sys/syspage.h> #include <unistd.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/debug.h> #include <sys/procfs.h> #include <sys/syspage.h> #include <sys/neutrino.h> #include <sys/time.h> #include <time.h> #include <fcntl.h> #include <devctl.h> #include <errno.h> #define MAX_CPUS 32 static float Loads[MAX_CPUS]; static _uint64 LastSutime[MAX_CPUS]; static _uint64 LastNsec[MAX_CPUS]; static int ProcFd = -1; static int NumCpus = 0; int find_ncpus(void) { return NumCpus; } int get_cpu(int cpu) { int ret; ret = (int)Loads[ cpu % MAX_CPUS ]; ret = max(0,ret); ret = min(100,ret); return( ret ); } static _uint64 nanoseconds( void ) { _uint64 sec, usec; struct timeval tval; gettimeofday( &tval, NULL ); sec = tval.tv_sec; usec = tval.tv_usec; return( ( ( sec * 1000000 ) + usec ) * 1000 ); } int sample_cpus( void ) { int i; debug_thread_t debug_data; _uint64 current_nsec, sutime_delta, time_delta; memset( &debug_data, 0, sizeof( debug_data ) ); for( i=0; i<NumCpus; i++ ) { /* Get the sutime of the idle thread #i+1 */ debug_data.tid = i + 1; devctl( ProcFd, DCMD_PROC_TIDSTATUS, &debug_data, sizeof( debug_data ), NULL ); /* Get the current time */ current_nsec = nanoseconds(); /* Get the deltas between now and the last samples */ sutime_delta = debug_data.sutime - LastSutime[i]; time_delta = current_nsec - LastNsec[i]; /* Figure out the load */ Loads[i] = 100.0 - ( (float)( sutime_delta * 100 ) / (float)time_delta ); /* Flat out strange rounding issues. */ if( Loads[i] < 0 ) { Loads[i] = 0; } /* Keep these for reference in the next cycle */ LastNsec[i] = current_nsec; LastSutime[i] = debug_data.sutime; } return EOK; } int init_cpu( void ) { int i; debug_thread_t debug_data; memset( &debug_data, 0, sizeof( debug_data ) ); /* Open a connection to proc to talk over.*/ ProcFd = open( "/proc/1/as", O_RDONLY ); if( ProcFd == -1 ) { fprintf( stderr, "pload: Unable to access procnto: %s\n",strerror( errno ) ); fflush( stderr ); return -1; } i = fcntl(ProcFd,F_GETFD); if(i != -1){ i |= FD_CLOEXEC; if(fcntl(ProcFd,F_SETFD,i) != -1){ /* Grab this value */ NumCpus = _syspage_ptr->num_cpu; /* Get a starting point for the comparisons */ for( i=0; i<NumCpus; i++ ) { /* * the sutime of idle thread is how much * time that thread has been using, we can compare this * against how much time has passed to get an idea of the * load on the system. */ debug_data.tid = i + 1; devctl( ProcFd, DCMD_PROC_TIDSTATUS, &debug_data, sizeof( debug_data ), NULL ); LastSutime[i] = debug_data.sutime; LastNsec[i] = nanoseconds(); } return(EOK); } } close(ProcFd); return(-1); } void close_cpu(void){ if(ProcFd != -1){ close(ProcFd); ProcFd = -1; } } int main(int argc, char* argv[]){ int i,j; init_cpu(); printf("System has: %d CPUs\n", NumCpus); for(i=0; i<20; i++) { sample_cpus(); for(j=0; j<NumCpus;j++) printf("CPU #%d: %f\n", j, Loads[j]); sleep(1); } close_cpu(); } 

如何获得免费(!)内存: http : //www.qnx.com/support/knowledgebase.html?id=50130000000mlbx

 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <err.h> #include <sys/stat.h> #include <sys/types.h> int main( int argc, char *argv[] ){ struct stat statbuf; paddr_t freemem; stat( "/proc", &statbuf ); freemem = (paddr_t)statbuf.st_size; printf( "Free memory: %d bytes\n", freemem ); printf( "Free memory: %d KB\n", freemem / 1024 ); printf( "Free memory: %d MB\n", freemem / ( 1024 * 1024 ) ); return 0; } 

我在我的C ++项目中使用下面的代码,它工作正常:

 static HANDLE self; static int numProcessors; SYSTEM_INFO sysInfo; double percent; numProcessors = sysInfo.dwNumberOfProcessors; //Getting system times information FILETIME SysidleTime; FILETIME SyskernelTime; FILETIME SysuserTime; ULARGE_INTEGER SyskernelTimeInt, SysuserTimeInt; GetSystemTimes(&SysidleTime, &SyskernelTime, &SysuserTime); memcpy(&SyskernelTimeInt, &SyskernelTime, sizeof(FILETIME)); memcpy(&SysuserTimeInt, &SysuserTime, sizeof(FILETIME)); __int64 denomenator = SysuserTimeInt.QuadPart + SyskernelTimeInt.QuadPart; //Getting process times information FILETIME ProccreationTime, ProcexitTime, ProcKernelTime, ProcUserTime; ULARGE_INTEGER ProccreationTimeInt, ProcexitTimeInt, ProcKernelTimeInt, ProcUserTimeInt; GetProcessTimes(self, &ProccreationTime, &ProcexitTime, &ProcKernelTime, &ProcUserTime); memcpy(&ProcKernelTimeInt, &ProcKernelTime, sizeof(FILETIME)); memcpy(&ProcUserTimeInt, &ProcUserTime, sizeof(FILETIME)); __int64 numerator = ProcUserTimeInt.QuadPart + ProcKernelTimeInt.QuadPart; //QuadPart represents a 64-bit signed integer (ULARGE_INTEGER) percent = 100*(numerator/denomenator); 

对于Linux您还可以使用/ proc / self / statm来获取包含关键进程内存信息的一行数字,这比从proc / self / status获得的一长串报告信息要快得多

http://man7.org/linux/man-pages/man5/proc.5.html

  /proc/[pid]/statm Provides information about memory usage, measured in pages. The columns are: size (1) total program size (same as VmSize in /proc/[pid]/status) resident (2) resident set size (same as VmRSS in /proc/[pid]/status) shared (3) number of resident shared pages (ie, backed by a file) (same as RssFile+RssShmem in /proc/[pid]/status) text (4) text (code) lib (5) library (unused since Linux 2.6; always 0) data (6) data + stack dt (7) dirty pages (unused since Linux 2.6; always 0)