VC++使用GetProcessTimes获取进程创建时间、销毁时间、用户态时间、内核态时间

2023-12-14 10:36:29

一、GetProcessTimes函数简介(微软MSDN)

微软提供了一个非常有用的API函数GetProcessTimes用来获取进程创建时间、销毁时间、用户态时间、内核态时间,msdn连接为:GetProcessTimes 函数 (processthreadsapi.h)
其函数原型为:

BOOL GetProcessTimes(
  [in]  HANDLE     hProcess,
  [out] LPFILETIME lpCreationTime,
  [out] LPFILETIME lpExitTime,
  [out] LPFILETIME lpKernelTime,
  [out] LPFILETIME lpUserTime
);

其参数如下:
参数
其返回值和函数说明如下:
返回值和库依赖

二、示例程序

相关示例程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <Psapi.h>
#include <winnt.h>
#include <winternl.h>
#include <chrono>
#include <iostream>

using namespace std;
using namespace std::chrono;

void test_GetProcessTimes()
{
	HANDLE     processHandle = GetCurrentProcess();
	DWORD      currentProcessId = GetProcessId(processHandle);
	FILETIME createTime, exitTime, kernelTime, userTime;
	// 获取当前进程的PID
	DWORD pid = GetCurrentProcessId();
	printf("pid: %d\t currentProcessId: %d\n", pid, currentProcessId);

	GetProcessTimes(processHandle, &createTime, &exitTime, &kernelTime, &userTime);
	printf("processHandle: %lu\t currentProcessId: %d\n", HandleToULong(processHandle), currentProcessId);
	printf("Create time: %lu\t       %lu\nExit Time: %lu\t     %lu\nKernel time: %lu\t       %lu\nUser time: %lu\t    %lu\n",
		createTime.dwLowDateTime, createTime.dwHighDateTime,
		exitTime.dwLowDateTime, exitTime.dwHighDateTime,
		kernelTime.dwLowDateTime, kernelTime.dwHighDateTime,
		userTime.dwLowDateTime, userTime.dwHighDateTime);

	::CloseHandle(processHandle);
}


// 返回进程pid创建时间到现在时间经过的秒数
double get_uptime_sec(DWORD pid)
{
	double r{ 0 };
	HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
	if (hProcess)
	{
		FILETIME creationTime, exitTime, kernelTime, userTime;
		if (::GetProcessTimes(
			hProcess, &creationTime, &exitTime, &kernelTime, &userTime)) {

			LARGE_INTEGER tCreate;
			tCreate.LowPart = creationTime.dwLowDateTime;
			tCreate.HighPart = creationTime.dwHighDateTime;
			std::cout << "tCreate: " << tCreate.QuadPart << std::endl;

			int64_t tt = (static_cast<int64_t>(creationTime.dwHighDateTime) << 32) | creationTime.dwLowDateTime;
			std::cout << "tt: " << tt << std::endl;

			SYSTEMTIME stCreate;
			FileTimeToSystemTime(&creationTime, &stCreate);
			r = (double)stCreate.wHour * 3600.0 +
				(double)stCreate.wMinute * 60.0 +
				(double)stCreate.wSecond +
				(double)stCreate.wMilliseconds / 1000.0;
			std::cout << "r: " << r << std::endl;
		}
		::CloseHandle(hProcess);
	}
	return r;
}

三、进一步扩展:获取每个进程一段时间内的CPU使用率

由于GetProcessTimes 函数可以获取某个进程的在内核模式下执行的时间量和用户模式下执行的时间量(以100纳秒为单位)。我们可以先使用NtQuerySystemInformation函数获取每个CPU核心的总的用户态、内核态、空闲时间总时间量sysTotalTime,然后遍历枚举当前系统所有运行进程,再用GetProcessTimes去获取每个进程的在内核模式下执行的时间量和用户模式下执行的时间量,除以sysTotalTime即为该进程的CPU使用率。开一个线程每隔一段时间,比如说250毫秒、500毫秒、1秒、2秒等定时轮询获取。
参考ProcessHacker的源代码,它里面也大体是这个思路。

四、参考资料

文章来源:https://blog.csdn.net/ccf19881030/article/details/134867831
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。