关闭

Windows系统使用状况统计

439人阅读 评论(0) 收藏 举报
分类:

参考: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

共同学习!!

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3275次
    • 积分:100
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档