现在的位置: 首页 > 综合 > 正文

Windows 进程在核心态和用户运行态时间比较源码解析

2014年09月05日 ⁄ 综合 ⁄ 共 1896字 ⁄ 字号 评论关闭
#include<windows.h>
#include<tlhelp32.h>
#include<iostream>
using namespace std;

DWORD GetKernelModePercentage(const FILETIME& ftKernel, const FILETIME& ftUser)
{
	//将FILETIME结构转化为64位整数
	ULONGLONG qwKernel = (((ULONGLONG)ftKernel.dwHighDateTime)<<32)+ftKernel.dwLowDateTime;
	ULONGLONG qwUser = (((ULONGLONG)ftUser.dwHighDateTime)<<32)+ftUser.dwLowDateTime;
	ULONGLONG qwTotal = qwKernel + qwUser;
	DWORD dwPct = (DWORD)(((ULONGLONG)100*qwKernel)/qwTotal);
	return (dwPct);
}

int main(int argc, char *argv[])
{
	if(argc < 2)
	{
		cout << "请给出你要查询的程序名" << endl;
		exit(0);
	}
	//对当前系统中运行的进程进行快照,收集关于当前运行进程的 一些信息
	HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	//对当前系统中的所有的进程进行一次快照,实际上获取到的是一张系统的进程表,后面虽然有0表示获取当前的进程,但是因为前面没有制定的参数,所以它被忽略

	PROCESSENTRY32 pe;       //定义了一个 存放快照信息的结构体
	::ZeroMemory(&pe,sizeof(pe));   //将这个结构体的内存范围都清零,类似于memset这种功能
	pe.dwSize = sizeof(pe);      //获取这段内存空间有多大
	BOOL bMore = ::Process32First(hSnapshot, &pe);  //返回真证明进程表中的第一个条目已经复制到缓冲区
	BOOL found = FALSE;
	while(bMore)
	{
		if(!strcmp(pe.szExeFile, argv[1]))   //在内存中截取当前运行进程的名称与你要检测的相比较
		{
			found = TRUE;
			HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe.th32ProcessID);//打开这个对应的进程
			if(hProcess != NULL)
			{
				FILETIME ftCreation, ftKernelMode, ftUserMode, ftExit;
				::GetProcessTimes(
					hProcess,
					&ftCreation,
					&ftExit,
					&ftKernelMode,
					&ftUserMode
					);
				/*
				BOOL WINAPI GetProcessTimes(
				 __in   HANDLE hProcess,
				__out  LPFILETIME lpCreationTime,
				 __out  LPFILETIME lpExitTime,
				 __out  LPFILETIME lpKernelTime,
				 __out  LPFILETIME lpUserTime
				);
				这是这个函数的声明部分,可以看出,他是接受一个进程的句柄之后,输出这个进程相应的一些时间
				*/
				DWORD dwPctKernel = ::GetKernelModePercentage(ftKernelMode, ftUserMode);
				cout << "Process ID:" << pe.th32ProcessID
					<< ",EXE file:" << pe.szExeFile
					<< ",%d in Kernel mode:" << dwPctKernel << endl;

				::CloseHandle(hProcess);
			}
		}
		bMore = ::Process32Next(hSnapshot, &pe);
	}
	if(found == FALSE)
	{
		cout << "当前系统没有这个可执行程序在运行" << endl;
		exit(0);
	}
	return 0;
}

源码都是课程设计报告上面的,但是我查了MSDN也就是官方的文档,注释应该写的很全,每一行代码的功能基本都KO掉了。

在测试的时候,在命令行提示符内先找到1-3的程序运行,然后再到1-2的目录下运行自己的程序格式入下(以自己的文件名为准)

1-2.exe 1-3.exe

在命令提示符中的1.2.exe文件夹 所在 路径运行上面这个命令,相应的进程在内核态下运行的一些信息就会出来

抱歉!评论已关闭.