查询系统和进程状态信息

windows C++ 


1. 系统CPU利用率


理论支持

1.CPU利用率:CPU工作时间与总时间的比值。

2.Windows下任务管理器CPU用率的由来:

        a.CPU使用率:在任务管理器的刷新周期内CPU工作时间与刷新周期的比值。
        b.任务管理器默认的刷新周期是1s。

3.windows下,CPU只会处于两种状态:陷入内核和陷入用户

4.若干公式:

        a.用率 = CPU工作时间 / 时间间隔 (一段时间内,如1s内

        b.工作时间 = 内核态工作时间 +用户态工作时间。

        c.时间间隔 = 工作时间 + 空闲时间 = 内核时间 + 用户时间。

5.当空闲时,CPU进入内核执行System Idle Process。打开任务管理器->进程->最下面,System Idle Process所持有CPU即此刻空闲CPU。故内核时间等于内核态工作时间与CPU整体空闲时间之和。


综上所述:

        A.CPU用率 = (用户时间 + 内核时间 - 空闲时间) / (用户时间 + 内核时间

        B.CPU用率 = (用户时间 + 内核时间 - 空闲时间)/ 间隔时间 


函数和结构体

1.函数GetSystemTimes

原型:BOOL GetSystemTimes(LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime)

返回值:成功返回0,否则非0

功能:获取CPU处于空闲、内核、用户态的时间。

        A.自开机以来

        B.所有CPU的时间和


2.FILETIME结构

typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME;

DWORD = unsigned long,4字节32位


3.提取FILETIME时间:

方法一

ULARGE_INTEGER ul;

ul.HighPart = ft.dwHighDateTime;
ul.LowPart = ft.dwLowDateTime;

ul.QuadPart即ft代表的时间,单位0.1微秒

方法二

ULONGLONG ull = ft.dwHighDateTime;

ull = ull<<32 | ft.dwLowDateTime;


4.ULARGE_INTEGER结构:

		typedef union _ULARGE_INTEGER {
		struct {
		DWORD LowPart;
		DWORD HighPart;
		};
		struct {
		DWORD LowPart;
		DWORD HighPart;
		} u;
		ULONGLONG QuadPart;
		} ULARGE_INTEGER, *PULARGE_INTEGER;

ULARGE_INTEGER实为联合体,专用于表示64位无符号大长整形。
将FILETIME还原为64位无符号大长整形:将FILETIME高32位、低32位分别赋值给ULARGE_INTEGER高、低32位,然后ULARGE_INTEGER的QuadPart即结果。


程序实现

ULONGLONG CompareFileTime(const FILETIME &ft1, const FILETIME &ft2)
{
	ULARGE_INTEGER ul1;
	ul1.HighPart = ft1.dwHighDateTime;
	ul1.LowPart = ft1.dwLowDateTime;

	ULARGE_INTEGER ul2;
	ul2.HighPart = ft2.dwHighDateTime;
	ul2.LowPart = ft2.dwLowDateTime;

	return ul2.QuadPart - ul1.QuadPart;
}

int GetSystemCpu(){
	FILETIME ftPreIdle, ftPreUser, ftPreKernel;
	FILETIME ftIdle, ftUser, ftKernel;

	if(!GetSystemTimes(&ftPreIdle, &ftPreKernel, &ftPreUser))
	{
		std::cout<<"First GetSystemTimes Error"<<std::endl;
		return;
	}
	
	Sleep(n);

	if(!GetSystemTimes(&ftIdle, &ftKernel, &ftUser))
	{
		std::cout<<"Second GetSystemTimes Error"<<std::endl;
		return;
	}

	ULONGLONG ullIdle = CompareFileTime(ftPreIdle, ftIdle);
	ULONGLONG ullKernel = CompareFileTime(ftPreKernel, ftKernel);
	ULONGLONG ullUser = CompareFileTime(ftPreUser, ftUser);

	double dCpu1 = (ullKernel+ullUser-ullIdle)*100.0 / (ullKernel+ullUser);
	double dCpu2 = (ullKernel+ullUser-ullIdle)*100.0 / (n*1000*10*iCpuNum);

	return static_cast<int>(dCpu1+0.5);
}

2. 进程CPU利用率

如果说系统CPU利用率是一段时间内所有进程运行时间占总时间的比值,则进程CPU利用率即为一段时间内该进程运行时间占总时间的比值,故:

进程CPU利用率 = 进程运行时间 / 总时间


辅助函数

1.函数GetProcessTimes

原型:BOOL GetProcessTimes(

HANDLE hProcess, LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME  lpKernelTime, LPFILETIME lpUserTime)

返回值:成功返回0,否则非0

功能:获取进程创建时间、退出时间、内核时间、用户时间。

        A.创建时间和退出时间是UNIX时间戳。
        B.若进程尚未退出,lpExitTime值不确定。
        C.lpKernelTime和lpUserTime要考虑多处理器情况。
        D.即便不需要创建时间和退出时间也必须保证传入的lpCreationTime和lpExitTime有意义。


程序实现

HANDLE GetProcessHandle(const std::string &sProcessName)
{
	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(pe32);

	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	BOOL bMore = Process32First(hProcessSnap, &pe32);
	while(bMore)
	{
		if(!sProcessName.compare(pe32.szExeFile))
		{
			HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
			return hProcess;
		}
		bMore=::Process32Next(hProcessSnap,&pe32);
	}

	std::cout<<"Not Found The Process Of Server:"<<sProcessName<<std::endl;
	return INVALID_HANDLE_VALUE;
}

int GetProcessCpu(const std::string &sProcessName)
{
	HANDLE hProcess = GetProcessHandle(sProcessName);
	if(INVALID_HANDLE_VALUE == hProcess)
	{
		std::cout<<"Get Process Handle Fail"<<std::endl;
		return -1;
	}

	SYSTEM_INFO si;
	GetSystemInfo(&si);
	int iCpuNum = si.dwNumberOfProcessors;

	FILETIME ftPreKernelTime, ftPreUserTime;
	FILETIME ftKernelTime, ftUserTime;
	FILETIME ftCreationTime, ftExitTime;

	if(!GetProcessTimes(hProcess, &ftCreationTime, &ftExitTime, &ftPreKernelTime, &ftPreUserTime))
	{
		std::cout<<"First GetProcessTimes Error:"<< GetLastError()<<std::endl;
		return -1;
	}

	Sleep(INTERVAL);

	if(!GetProcessTimes(hProcess, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime))
	{
		std::cout<<"GetProcessTimes Error:"<< GetLastError()<<std::endl;
		return -1;
	}

	ULONGLONG ullKernelTime = CompareFileTime(ftPreKernelTime, ftKernelTime);
	ULONGLONG ullUserTime = CompareFileTime(ftPreUserTime, ftUserTime);
	
	double dCpu = (ullKernelTime+ullUserTime)*100.0 / (cpuNum*INTERVAL*10000);

	return static_cast<int>(dCpu + 0.5);
}

原文地址:https://www.cnblogs.com/chaikefusibushiji/p/6775783.html