Khi sử dụng hàm GetIdleTime theo khuyến nghị MSDN để tính toán tỷ lệ CPU, một số nền tảng cho kết quả bất thường nằm ngoài khoảng 0-100%. Dưới đây là giải pháp thay thế:
Phương pháp đo thời gian nhàn rỗi
void TinhToanSuDungCPU() {
DWORD batDau, ketThuc;
DWORD nhanRoBatDau, nhanRoKetThuc;
int mauHienTai[10] = {0};
int tongMau = 0;
int dem = 0;
while(1) {
batDau = GetTickCount();
nhanRoBatDau = GetIdleTime();
Sleep(100);
ketThuc = GetTickCount();
nhanRoKetThuc = GetIdleTime();
int tiLeNhanRo = (100 * (nhanRoKetThuc - nhanRoBatDau)) / (ketThuc - batDau);
if(dem < 10) {
mauHienTai[dem] = tiLeNhanRo;
dem++;
if(dem == 10) {
for(int i = 0; i < 10; i++)
tongMau += mauHienTai[i];
int trungBinh = tongMau / 10;
g_TiLeNhanRoCPU = trungBinh;
dem = 0;
tongMau = 0;
}
}
}
}
Phương pháp không sử dụng GetIdleTime
DWORD ChuyenDoiThoiGianLuong(FILETIME* pFtKernel, FILETIME* pFtUser) {
ULONGLONG thoiGianTong = ((ULONGLONG)pFtKernel->dwHighDateTime << 32 | pFtKernel->dwLowDateTime)
+ ((ULONGLONG)pFtUser->dwHighDateTime << 32 | pFtUser->dwLowDateTime);
return (DWORD)(thoiGianTong / 10000);
}
DWORD WINAPI TheoDoiCPU(LPVOID lpParam) {
DWORD idLuong;
HANDLE hLuongNhanRo = CreateThread(NULL, 0, [](LPVOID) -> DWORD {
while(1) {}
return 0;
}, NULL, CREATE_SUSPENDED, &idLuong);
SetThreadPriority(hLuongNhanRo, THREAD_PRIORITY_IDLE);
ResumeThread(hLuongNhanRo);
DWORD thoiGianLuongTruoc = 0;
DWORD thoiGianHeThongTruoc = 0;
while(1) {
Sleep(1000);
SuspendThread(hLuongNhanRo);
FILETIME ftTao, ftKetThuc, ftKernel, ftUser;
DWORD thoiGianHeThongHien = GetTickCount();
GetThreadTimes(hLuongNhanRo, &ftTao, &ftKetThuc, &ftKernel, &ftUser);
DWORD thoiGianLuongHien = ChuyenDoiThoiGianLuong(&ftKernel, &ftUser);
DWORD suDungCPU = 0;
if(thoiGianHeThongHien != thoiGianHeThongTruoc) {
DWORD thoiGianNhanRo = (thoiGianLuongHien - thoiGianLuongTruoc) * 100;
DWORD khoangThoiGian = thoiGianHeThongHien - thoiGianHeThongTruoc;
suDungCPU = 100 - (thoiGianNhanRo / khoangThoiGian);
}
thoiGianHeThongTruoc = thoiGianHeThongHien;
thoiGianLuongTruoc = thoiGianLuongHien;
RETAILMSG(1, (TEXT("CPU: %d%%\r\n"), suDungCPU));
ResumeThread(hLuongNhanRo);
}
}