我曾經負責從運行的應用程序內部肯定如下性能參數的任務: html
該代碼必須在Windows和Linux上運行。 儘管這彷佛是一項標準任務,但在手冊(WIN32 API,GNU文檔)以及Internet上找到必要的信息仍是花了我幾天的時間,由於關於該主題的信息太多,不完整/不正確/過期發如今那裏。 linux
爲了使其餘人免於遭受一樣的麻煩,我認爲將全部分散的信息以及經過反覆試驗發現的信息收集到一個地方是一個好主意。 windows
在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; }
我也但願能爲Mac OS X找到相似的信息。 因爲不在這裏,我本身出去挖了出來。 這是我發現的一些東西。 若是有人有其餘建議,我很想聽聽他們的建議。 ide
在Mac OS X上,這是一個棘手的問題,由於它不使用預設的交換分區或相似Linux的文件。 這是Apple文檔中的條目: 函數
注意:與大多數基於Unix的操做系統不一樣,Mac OS X不爲虛擬內存使用預分配的交換分區。 相反,它將使用計算機引導分區上的全部可用空間。 性能
所以,若是您想知道仍有多少虛擬內存可用,則須要獲取根分區的大小。 您能夠這樣作: ui
struct statfs stats; if (0 == statfs("/", &stats)) { myFreeSwap = (uint64_t)stats.f_bsize * stats.f_bfree; }
使用「 vm.swapusage」鍵調用systcl可提供有關交換使用狀況的有趣信息: this
sysctl -n vm.swapusage vm.swapusage: total = 3072.00M used = 2511.78M free = 560.22M (encrypted)
若是須要更多的交換,則上面顯示的交換總使用量不會改變,如上一節所述。 所以,總數其實是當前的交換總數。 在C ++中,能夠經過如下方式查詢此數據: atom
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」,我懷疑還有一種更可移植的方式來訪問這些值。
您可使用task_info
函數獲取有關當前進程的統計信息。 這包括您的進程的當前駐留大小和當前虛擬大小。
#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;
可使用sysctl
系統功能來得到系統中可用的物理RAM量,以下所示:
#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);
您能夠從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中有五種類型的內存頁面。它們以下:
值得一提的是,因爲Mac OS X有時可能會顯示不多的實際可用內存,所以它可能沒法很好地代表能夠當即使用多少內存。
請參閱上面的「個人進程當前使用的虛擬內存」。 相同的代碼適用。
因爲這就像一個「代碼維基頁面」,所以我想從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; }
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.
我在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);