一、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;// 獲取當前進程的PIDDWORD 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
的源代碼,它里面也大體是這個思路。
四、參考資料
-
getProcessTimes 函數 (processthreadsapi.h)
-
How to retrieve the running-time of a process
-
How to get Process Uptime in Windows