环境: window7 64位 cpu Intel i3-4170
一、程序运行如下:
i3-4170是双核四线程。我暂时没有找出区分线程数跟核心数的区别。这个问题以后再去解决吧
二、编程前准备 ( 可以直接跳到三、 处,源码中已经有了)
获得cpu温度的方法是读取cpu寄存器。由于windows的保护机制,无法直接使用汇编程序读取寄存器,因此使用了WinRing0库。
下载链接如下:
http://download.youkuaiyun.com/detail/xiufeng_wang/1140396
需要用到的文件如下:
WinRing0.dll
WinRing0.sys
WinRing0x64.dll
WinRing0x64.sys
WinRing0.lib
OlsApi.h
其中WinRing0.lib、OlsApi.h放在编译文件处,其他的需要放在.exe文件夹下。
三、源码如下:
http://download.youkuaiyun.com/detail/jiaowosongsong/9496571
四、源码介绍
先来看看主函数部分(readPcInfo.cpp)
好吧主函数基本什么都没有,还是跳过吧。
#include "stdafx.h"
#include "ReadCpuInfo.h"
//#include "OlsApi.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
ReadCpuInfo myCpu; //生成对象
//cout << InitializeOls() << endl;;
//cout << sysInfo.dwNumberOfProcessors << endl;
//cout << sysInfo.dwActiveProcessorMask << endl;
while (1)
{
myCpu.ReadCpuTemp(); //调用对象函数,读取cpu温度
//cout << myCpu.cpuTemp[0] << endl;
myCpu.SysTimeDisplay(); //显示系统时间
myCpu.CpuTempDisplay(); //显示cpu温度
Sleep(1000);
system("cls");
}
return 0;
}
运用WinRing0获得cpu温度部分:
1.ReadCpuInfo.h
主要就是加载了WinRing0.lib,函数1和函数2 完成了整个流程;
#pragma once
#include<windows.h>
#include "OlsApi.h" //头文件
#pragma comment (lib,"WinRing0.lib") //加载lib
#define CONSOLE_PRINT 1
class ReadCpuInfo
{
private:
char fileName[30];
public:
int cpuTemp[8];
int coreNumber; //获得的线程数
int Tjmax;
public:
ReadCpuInfo();
virtual ~ReadCpuInfo();
public:
//void ReadCpuTempInit();
void ReadCpuTemp(); //函数2
void CpuTempDisplay();
void SysTimeDisplay();
void clearRecordFile();
private:
void ReadCpuInfoInit(); //函数1
void ReadCpuInfoExit();
void RecordCpuInfo(char *buf);
int CheckAndPrint(char message[], BOOL flag);
};
2.ReadCpuInfo.cpp 函数实现
#include "stdafx.h"
#include "ReadCpuInfo.h"
#include <string.h>
ReadCpuInfo::ReadCpuInfo()
{
ReadCpuInfoInit(); //构造函数初始化dll
strcpy_s(fileName, "CpuInfoRecord.txt");
}
ReadCpuInfo::~ReadCpuInfo()
{
ReadCpuInfoExit();
}
void ReadCpuInfo::ReadCpuTemp() //主要函数
{
for (size_t i = 0; i < coreNumber; i++) //遍历CPU
{
int mask = 0x01 << i;
SetProcessAffinityMask(GetCurrentProcess(), mask);//设置当前使用线程(CPU)
DWORD eax, ebx, ecx, edx;
Rdmsr(0x19c, &eax, &edx); //读取温度寄存器(eax&0x7f0000可以获得温度数据)
cpuTemp[i] = Tjmax - ((eax & 0x7f0000) >> 16);//实际温度= Tjmax - 温度数据
}
}
void ReadCpuInfo::ReadCpuInfoInit() //初始化
{
if (true == CheckAndPrint("Init DLL function", InitializeOls())) //dll的初始化
{
if (true == CheckAndPrint("IsCpuid function", IsCpuid())) //判断是否支持Cpuid
{
if (true == CheckAndPrint("Ismsr function", IsMsr())) //是否支持Rdmsr
{
DWORD eax, ebx, ecx, edx;
Rdmsr(0x1A2, &eax, &edx); //读取寄存器
Tjmax = (eax & 0xff0000) >> 16; //获得Tjmax
//printf("%d\n", Tjmax); //show max temperature
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
coreNumber = sysInfo.dwNumberOfProcessors; //获得线程数
SetProcessAffinityMask(GetCurrentProcess(), 1); //切换到第一个cpu;
}
}
}
}
void ReadCpuInfo::ReadCpuInfoExit()
{
DeinitializeOls();
}
int ReadCpuInfo::CheckAndPrint(char message[], BOOL flag)
{
if (flag)
{
printf("%s is checked Enable!\n", message);
return 1;
}
else
{
printf("%s is checked unEnabled!\n", message);
return 0;
}
}
void ReadCpuInfo::CpuTempDisplay()
{
for (size_t i = 0; i < coreNumber; i++)
{
char buf[1024] = "";
#if (CONSOLE_PRINT)
printf("Core #%d: %dC\n", i, cpuTemp[i]);
#else
#endif
sprintf_s(buf, "Core #%d: %dC\n", i, cpuTemp[i]);
RecordCpuInfo(buf);
}
}
void ReadCpuInfo::SysTimeDisplay()
{
clearRecordFile();
SYSTEMTIME start; //windows.h中
GetLocalTime(&start);//time.h的tm结构体一样的效果
//printf("%d\n", start.wHour);
#if (CONSOLE_PRINT)
printf("date: %02d/%02d/%02d\n",
start.wYear, start.wMonth, start.wDay);
printf("time: %02d:%02d:%02d\n",
start.wHour, start.wMinute, start.wSecond);
#else
#endif
char buf[1024] = "";
sprintf_s(buf, "date: %02d/%02d/%02d\n", start.wYear, start.wMonth, start.wDay);
RecordCpuInfo(buf);
memset(buf, 0, sizeof(buf));
sprintf_s(buf, "time: %02d:%02d:%02d\n",start.wHour, start.wMinute, start.wSecond);
RecordCpuInfo(buf);
}
void ReadCpuInfo::RecordCpuInfo(char *buf)
{
FILE *fp;
fopen_s(&fp,fileName, "a+");
if (fp == NULL)
{
printf("file open error!\n");
return;
}
else
{
fwrite(buf, strlen(buf), 1, fp);
}
fclose(fp);
}
void ReadCpuInfo:: clearRecordFile()
{
FILE *fp;
fopen_s(&fp,fileName, "w+");
if (fp == NULL)
{
printf("file open error!\n");
return ;
}
fclose(fp);
}
大家看完后估计还是一头雾水,更详细的原理可以看看其他博客:
http://blog.youkuaiyun.com/zhangweilst/article/details/43857371