有不少朋友问在qnx下如何获取内存及cpu占有率等等,想到两年前自己做过一个类似windows里的任务管理器的东东,里面有一部分就是获取内存,cpu,磁盘及进程信息的GUI程序,记得也美其名曰xxxTaskMan。把里面的关键代码写下来供兄弟们参考。界面部分就不公布了,无非是一些窗口,按钮,list等等。
一、ProcInfo.h
- // ProcInfo.h: interface for the CProcInfo class.
- //
- //
-
- #if !defined(AFX_PROCINFO_H__E3782DFC_59DE_45FC_BF1F_D8C8BF0181C1__INCLUDED_)
- #define AFX_PROCINFO_H__E3782DFC_59DE_45FC_BF1F_D8C8BF0181C1__INCLUDED_
-
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
-
-
class CProcInfo
- {
-
public:
- CProcInfo();
- virtual ~CProcInfo();
-
-
-
public:
- static void InitSysInfo();
- static void ClearSysInfo();
- static int GetFreeMem();
- static int GetTotalMem();
- static int GetFreeMemPercent();
- static void GetSysInfo(int &TotalMem,int &CpuSpeed,int &BootTime,char *pszCpuName);
- static void GetDiskInfo(int &Total,int &Free);
- static int GetFreeDiskPercent();
- static int normalize_data_size(int &size);
-
- static bool GetProcName(const int iPid,char *pszProcName,int &fd);
- static bool GetSingleProcInfo(const int fd,long &StartTsp,int &CpuTime,int &MemSize);
-
-
private:
- static int s_iTotalMem;
- static int s_iCpuSpeed;
- static int s_iBootTime;
- static char s_strCpuName[32];
-
- static int s_hSysProc;
- static int s_hRootFile;
- };
-
- #endif // !defined(AFX_PROCINFO_H__E3782DFC_59DE_45FC_BF1F_D8C8BF0181C1__INCLUDED_)
-
使用方法,启动后先调用一次InitSysInfo(),结束后调用一次ClearSysInfo()进行清理。
2、ProcInfo.cpp代码
- // ProcInfo.cpp: implementation of the CProcInfo class.
- //
- //
-
- #include <errno.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/iofunc.h>
- #include <sys/dispatch.h>
- #include <sys/neutrino.h>
- #include <sys/procfs.h>
- #include <sys/stat.h>
-
- #include "ProcInfo.h"
- #include <libgen.h>
-
- //
- // Construction/Destruction
- //
-
int CProcInfo::s_iTotalMem;
-
int CProcInfo::s_iCpuSpeed;
-
int CProcInfo::s_iBootTime;
-
char CProcInfo::s_strCpuName[32]={'/0'};
-
-
-
int CProcInfo::s_hSysProc=-1;
-
int CProcInfo::s_hRootFile=-1;
-
-
- CProcInfo::CProcInfo()
- {
-
- }
-
- CProcInfo::~CProcInfo()
- {
-
- }
-
-
void CProcInfo::InitSysInfo()
- {
- char buffer[50];
- procfs_sysinfo *sysinfo;
- struct cpuinfo_entry *cpu;
- int i;
-
- sprintf(buffer, "/proc");
-
- if ((s_hSysProc = open(buffer, O_RDONLY)) == -1)
- printf( "couldn't open %s: %s/n", buffer, strerror(errno));
-
- sysinfo = (procfs_sysinfo *)buffer;
- if (devctl(s_hSysProc, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
- printf( "couldn't get info for %s: %s/n", buffer, strerror(errno));
-
- i = sysinfo->total_size;
- if(!(sysinfo = (procfs_sysinfo *)alloca(i)))
- printf( "couldn't get memory for %s: %s/n", buffer, strerror(errno));
-
- if (devctl(s_hSysProc, DCMD_PROC_SYSINFO, sysinfo, i, 0) != EOK)
- printf( "couldn't get info for %s: %s/n", buffer, strerror(errno));
-
- s_iTotalMem = _SYSPAGE_ENTRY(sysinfo, system_private)->ramsize;
- s_iBootTime = _SYSPAGE_ENTRY(sysinfo, qtime)->boot_time;
- cpu = _SYSPAGE_ENTRY(sysinfo, cpuinfo);
- // printf("%s ", &_SYSPAGE_ENTRY(sysinfo, strings)->data[cpu->name]); //实际name
- strcpy(s_strCpuName,"Cyrix X86");
- s_iCpuSpeed=cpu->speed;
- }
-
void CProcInfo::ClearSysInfo()
- {
- close(s_hSysProc);
- s_hSysProc=-1;
- close(s_hRootFile);
- s_hRootFile=-1;
- }
-
-
void CProcInfo::GetSysInfo(int &TotalMem,int &CpuSpeed,int &BootTime,char *pszCpuName)
- {
- TotalMem=s_iTotalMem;
- CpuSpeed=s_iCpuSpeed;
- BootTime=s_iBootTime;
- if (pszCpuName)
- {
- strcpy(pszCpuName,s_strCpuName);
- }
- }
-
-
int CProcInfo::GetFreeMem()
- {
- if (s_hSysProc==-1)
- {
- s_hSysProc=open("/proc", O_RDONLY);
- }
- struct stat st;
- if (fstat(s_hSysProc, &st) == -1)
- printf( "couldn't get stat info for %s: %s/n", "/proc", strerror(errno));
- return st.st_size;
- }
-
int CProcInfo::GetTotalMem()
- {
- return s_iTotalMem;
- }
-
-
int CProcInfo::GetFreeMemPercent()
- {
- int freemem=GetFreeMem();
- return ( (int)( freemem*100.0/s_iTotalMem ) );
- }
-
-
int CProcInfo::GetFreeDiskPercent()
- {
- int iTotal,iFree;
- GetDiskInfo(iTotal,iFree);
- return ( (int)( iFree*100.0/iTotal ) );
- }
-
-
-
int CProcInfo::normalize_data_size(int &size) {
- char sym = 0;
- if (size > 8192) {
- size /= 1024;
- sym = 'K';
- if (size > 8192) {
- size /= 1024;
- sym = 'M';
- }
- if (size > 8192) {
- size /= 1024;
- sym = 'G';
- }
- if (size > 8192) {
- size /= 1024;
- sym = 'T';
- }
- }
- return sym;
- }
-
-
void CProcInfo::GetDiskInfo(int &Total,int &Free)
- {
- if (-1==s_hRootFile)
- {
- s_hRootFile = open("/",O_RDONLY);
- }
- if (-1==s_hRootFile)
- {
- Total=-1;
- Free=-1;
- return;
- }
- struct statvfs FileBuff;
- int tmpret=0;
-
- if (-1==(tmpret=fstatvfs(s_hRootFile,&FileBuff)))
- {
- printf("fstatvfs ret=%d/n",tmpret);
- printf("fstatvfs is:%s/n",strerror(tmpret));
- close(s_hRootFile);
- Total=-1;
- Free=-1;
- return ;
- }
-
- // printf("f_blocks=%d,bfree=%d,f_bsize=%ld/n",FileBuff.f_blocks,FileBuff.f_bfree,FileBuff.f_bsize);
- // printf("DT=%ld,DF=%ld/n",FileBuff.f_blocks*FileBuff.f_bsize,FileBuff.f_bfree*FileBuff.f_bsize);
-
- Total=FileBuff.f_blocks*FileBuff.f_bsize;
- Free=FileBuff.f_bfree*FileBuff.f_bsize;
- }
-
-
-
bool CProcInfo::GetProcName(const int iPid,char *pszProcName,int &fd)
- {
- if (!pszProcName)
- {
- return false;
- }
-
- char buf[PATH_MAX + 1];
- struct dinfo_s {
- procfs_debuginfo info;
- char pathbuffer[PATH_MAX]; /* 1st byte is info.path[0] */
- }dinfo;
-
- sprintf(buf, "/proc/%d/as", iPid);
-
- if ((fd = open(buf, O_RDONLY|O_NONBLOCK)) == -1){
- return false;
- }
-
- if (devctl(fd, DCMD_PROC_MAPDEBUG_BASE, &dinfo, sizeof(dinfo), NULL) != EOK) {
- close(fd);
- return false;
- }
-
- strcpy(pszProcName,basename(dinfo.info.path));
- return true;
- }
-
- //StartTsp:单位:秒
- //CpuTime:单位:毫秒
- //MemSize:单位:字节
-
bool CProcInfo::GetSingleProcInfo(const int fd,long &StartTsp,int &CpuTime,int &MemSize)
- {
-
- procfs_info infos;
- if (-1==fd)
- {
- return false;
- }
-
- if (devctl(fd, DCMD_PROC_INFO, &infos, sizeof infos, 0) != EOK) {
- return false;
- }
-
- StartTsp=infos.start_time/1000000000;
- CpuTime=(infos.stime + infos.utime)/1000000;
-
- //MemSize
- MemSize=0;//
- procfs_mapinfo *mapinfos = NULL;
- static int num_mapinfos = 0;
- procfs_mapinfo *mapinfo_p;
- int flags = ~0, err, num, i;
-
-
- // Get the number of map entrys
- if((err = devctl(fd, DCMD_PROC_MAPINFO, NULL, 0, &num )) != EOK)
- {
- printf("failed devctl num mapinfos - %d (%s)/n", err, strerror(err));
- return false;
- }
-
- // malloc enough memory for all of them
- if ( (mapinfos = (procfs_mapinfo*)malloc( num*sizeof(procfs_mapinfo) )) == NULL )
- {
- printf("failed malloc - %d (%s)/n", err, strerror(err));
- return false;
- }
-
- num_mapinfos = num;
- mapinfo_p = mapinfos;
-
- // fill the map entrys
- if((err = devctl(fd, DCMD_PROC_MAPINFO, mapinfo_p, num*sizeof(procfs_mapinfo), &num)) != EOK)
- {
- printf("failed devctl mapinfos - %d (%s)/n", err, strerror(err));
- free(mapinfos);
- return false;
- }
-
- if (num>num_mapinfos)
- {
- num=num_mapinfos;
- }
-
- //
- // Run through the list of mapinfo's, and store the data and text info
- // so we can print it at the bottom of the loop.
- //
- for ( mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++ )
- {
- if ( !(mapinfo_p->flags & flags) )
- mapinfo_p->ino = 0;
-
- if ( mapinfo_p->ino == 0 ) /* already visited */
- continue;
- MemSize+=mapinfo_p->size;
- }
- free(mapinfos);
-
- return true;
- }
-
3、CpuUsed.h
- // CpuUsed.h: interface for the CCpuUsed class.
- //
- //
-
- #if !defined(AFX_CPUUSED_H__DA812B5A_099E_43F0_9C27_E84A9F0A8E78__INCLUDED_)
- #define AFX_CPUUSED_H__DA812B5A_099E_43F0_9C27_E84A9F0A8E78__INCLUDED_
-
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
-
- #include "QnxHardTimer.h"
-
-
class CCpuUsed : public CQnxHardTimer
- {
-
public:
- CCpuUsed();
- virtual ~CCpuUsed();
-
- virtual void RepeatTimerThread();
-
- int GetCpuUsed();
-
-
public:
- static CCpuUsed s_CpuUsed;
-
-
protected:
- int m_iCpuUsed;
-
- clockid_t m_iClockID;
- uint64_t m_ut_old;
- struct timespec m_tt_old;
- };
-
- #endif // !defined(AFX_CPUUSED_H__DA812B5A_099E_43F0_9C27_E84A9F0A8E78__INCLUDED_)
-
4、CpuUsed.cpp
- // CpuUsed.cpp: implementation of the CCpuUsed class.
- //
- //
- #include <stdint.h>
- #include <stdio.h>
- #include "CpuUsed.h"
-
- //
- // Construction/Destruction
- //
- CCpuUsed CCpuUsed::s_CpuUsed;
-
- CCpuUsed::CCpuUsed()
- {
- m_iClockID=ClockId(1, 1); //取空闲线程;
- m_ut_old=0;
- }
-
- CCpuUsed::~CCpuUsed()
- {
-
- }
-
-
void CCpuUsed::RepeatTimerThread()
- {
- uint64_t ut_now=0;
- struct timespec tt_now;
- uint64_t ut_sub; //时间差
- uint64_t ut_tmp;
- ClockTime(m_iClockID, NULL, &ut_now);
- clock_gettime( CLOCK_REALTIME, &tt_now);
- ut_tmp=tt_now.tv_sec-m_tt_old.tv_sec;
- ut_sub=ut_tmp*1000000000+tt_now.tv_nsec-m_tt_old.tv_nsec;
- m_iCpuUsed=(int)( ((float)(ut_sub-(ut_now-m_ut_old))/(float)ut_sub)*100 );
- m_ut_old=ut_now;
- m_tt_old=tt_now;
- // printf("m_iCpuUsed=%d%%/n",m_iCpuUsed);
- }
-
-
int CCpuUsed::GetCpuUsed()
- {
- if (m_iCpuUsed>100)
- {
- return 100;
- }else if (m_iCpuUsed<0)
- {
- return 0;
- }else
- return m_iCpuUsed;
- }
-
注意,CCpuUsed类继承了我自己封装的一个CQnxHardTimer,其实也就是一个定时器,改定时器会重复调用RepeatTimerThread(),在这里面就可以进行系统cpu占用率的计算。用户只需要调用GetCpuUsed()就可以了。
5、参考资料
pidin的源码。在qnx已公开的源码里就有。