Windows系统使用状况统计
参考:http://blog.csdn.net/morewindows/article/details/8459219
http://blog.csdn.net/morewindows/article/details/8678359
本篇大致统计了在win7下可用的内存整体使用,CPU整体统计,与网络流量统计。
1. 内存使用状况
主要用到了数据结构MEMORYSTATUSEX m_memoryStatusEx;来接收内存相关信息;结构如下:
typedef struct _MEMORYSTATUSEX {
DWORD dwLength; // 结构体自用大小
DWORD dwMemoryLoad; // 获取当前内存使用率
DWORDLONG ullTotalPhys; // 获取总的物理内存数量
DWORDLONG ullAvailPhys; // 获取当前可用的物理内存数量
DWORDLONG ullTotalPageFile; // 获取系统页面总量
DWORDLONG ullAvailPageFile; // 获取系统闲置页面数量
DWORDLONG ullTotalVirtual; // 获取系统虚拟内存总量
DWORDLONG ullAvailVirtual; // 获取系统可用虚拟内存数量
DWORDLONG ullAvailExtendedVirtual; // 可用的扩展虚拟内存(保留值,暂时不使用)
} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;
这个结构体大包含了内存使用状况的大致信息。
要获取这些信息,可以调用GlobalMemoryStatusEx函数,至于GlobalMemoryStatus函数,作为前者的前身,会逐渐的被前者替代,而前者又是向下兼容的,所以推荐大家使用前者。
WINBASEAPI
BOOL
WINAPI
GlobalMemoryStatusEx(
__out LPMEMORYSTATUSEX lpBuffer /* _MEMORYSTATUSEX 结构体指针 */
);
大致情况就是这样,核心代码:
BOOL CMemory::GetMemoryStatus()
{
m_memoryStatusEx.dwLength = sizeof(m_memoryStatusEx);
return ::GlobalMemoryStatusEx(&m_memoryStatusEx); // 核心函数
}
2.CPU整体统计
主要使用了GetSystemTimes函数和FILETIME结构体
1) FILETIME结构体
结构持有的64位无符号的文件的日期和时间值;此值表示自1601年1月1日开始的100纳秒为单位的时间(摘自百科)
typedef struct _FILETIME {
DWORD dwLowDateTime; // 文件时间的低32位值
DWORD dwHighDateTime; // 文件时间的高32位值
} FILETIME, *PFILETIME, *LPFILETIME;
2)GetSystemTimes函数
BOOL
WINAPI
GetSystemTimes(
__out_opt LPFILETIME lpIdleTime, // CPU空闲时间
__out_opt LPFILETIME lpKernelTime, // CPU内核占用时间
__out_opt LPFILETIME lpUserTime // CPU用户占用时间
);
3.核心算法:
int CCPU::GetCPUUsageRate()
{
int cpuUsageRate = -1;
FILETIME ftKernel, ftUser, ftIdle;
if (!(GetSystemTimes(&ftIdle, &ftKernel, &ftUser)))
{
return cpuUsageRate;
}
uint64 fCPUKernelTime = FileTimeToUInt64(&ftKernel);
uint64 fCPUUserTime = FileTimeToUInt64(&ftUser);
uint64 fCPUIdleTime = FileTimeToUInt64(&ftIdle);
/*
deltaUser = fCPUUserTime - m_fPreCPUUserTime;
deltaKernel = fCPUKernelTime - m_fPreCPUKernelTime;
deltaIdle = fCPUIdleTime - m_fPreCPUIdleTime;
cpu利用率 cpuUsageRate = (100 * (deltaUser + deltaKernel - deltaIdle) / (deltaUser + deltaKernel);
*/
uint64 varAll = (fCPUUserTime - m_fPreCPUUserTime) + (fCPUKernelTime - m_fPreCPUKernelTime);
cpuUsageRate = (100 * (varAll - fCPUIdleTime + m_fPreCPUIdleTime) / varAll);
m_fPreCPUKernelTime = fCPUKernelTime;
m_fPreCPUUserTime = fCPUUserTime;
m_fPreCPUIdleTime = fCPUIdleTime;
return cpuUsageRate;
}
3.网络流量统计:
主要用到了结构体MIB_IFTABLE,MIB_IFROW; 函数GetIfTable.
1)结构体MIB_IFTABLE
typedef struct _MIB_IFTABLE {
DWORD dwNumEntries; // 数组中接口条目的数量
MIB_IFROW table[ANY_SIZE]; // 包含MIB_IFROW接口条目的数组
} MIB_IFTABLE, *PMIB_IFTABLE;
从上面结构体可以看出,这个table数组的实际大小是第一个参数元素dwNumEntries,而#define ANY_SIZE 1 只是将数组初始化,所以使用时会再进行一次数组大小的分配,而这个工作应该是由函数GetIfTable完成的,数组中实际有内容的大小应该是dwNumEntries。
2)结构体MIB_IFROW
typedef struct _MIB_IFROW {
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
IF_INDEX dwIndex;
IFTYPE dwType;
DWORD dwMtu;
DWORD dwSpeed
DWORD dwPhysAddrLen;
UCHAR bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
INTERNAL_IF_OPER_STATUS dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets; // <--接收的字节数
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets; // <--发送的字节数
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
UCHAR bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;
这个结构体比较复杂,这里只用到了<--的字段
3.核心算法
bool CNetflow::NetflowStat()
{
if (!CheckNetStat())
{
m_netStat = NET_NOT_CONNECT;
return false;
}
m_received = 0;
m_sended = 0;
m_netStat = NET_CONNECT;
PMIB_IFTABLE pMIBTable = NULL;
DWORD dwAdapters = 0;
// 接口表按升序排序
ULONG uRetCode = GetIfTable(pMIBTable, &dwAdapters, TRUE);
if (uRetCode == ERROR_NOT_SUPPORTED)
{
return false;
}
if (uRetCode == ERROR_INSUFFICIENT_BUFFER)// 可用内存缓冲不足
{
pMIBTable = (PMIB_IFTABLE)new BYTE[dwAdapters]; // 重新分配pMIBTable大小,数组table大小应该是(dwAdapters字节减去一个DWORD的大小)/ sizeof(MIB_IFROW)
}
GetIfTable(pMIBTable, &dwAdapters, TRUE);
// 计算出接收与发送的字节的总数
for (UINT i = 0; i < pMIBTable->dwNumEntries; i++)
{
MIB_IFROW row = pMIBTable->table[i];
m_received += row.dwInOctets;
m_sended += row.dwOutOctets;
}
m_bandIn = m_received - m_preReceived;
m_bandOut = m_sended - m_preSended;
if (m_received <= 0)
{
m_bandIn = 0;
}
if (m_sended <= 0)
{
m_bandOut = 0;
}
m_preReceived = m_received;
m_preSended = m_sended;
delete []pMIBTable;
pMIBTable = NULL;
return true;
}
目前只有这三个简单的统计,后续会再添加。
另外工程是用VS2010编译,如果您的工作环境低于2010,那么中以将源文件拷贝出来,新建工程。
最后附上下载链接:
http://download.csdn.net/detail/yuanmushen/6640637
共同学习!!