golang利用gco获取windows系统cpu信息

mange · · 1085 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

# 效果图 ![](https://img-blog.csdnimg.cn/20201229214544347.png#pic_center) # 原理: 1. 调用汇编 cpuid指令 2. 调用 windows.h 的 GetSystemTimes # 细节注意 1. malloc开辟的空间要在使用结束后用free回收,具体写法如下代码 # 代码 ```go // 代码出处我的开源项目: https://github.com/mangenotwork/servers-online-manage // 获取windows系统cpu信息与使用率实例 package main /* #include <stdio.h> #include <conio.h> #include <windows.h> struct cpuid_result { DWORD eax; DWORD ebx; DWORD ecx; DWORD edx; }; // 执行汇编cpuid static inline struct cpuid_result cpuid(unsigned int op) { struct cpuid_result result; __asm volatile( "mov %%ebx, %%edi;" "cpuid;" "mov %%ebx, %%esi;" "mov %%edi, %%ebx;" : "=a" (result.eax), "=S" (result.ebx), "=c" (result.ecx), "=d" (result.edx) : "0" (op) : "edi"); return result; } static inline unsigned int cpuid_eax(unsigned int op) { //unsigned int eax, ebx, ecx, edx; struct cpuid_result regs; regs = cpuid(op); return regs.eax; } void get_cpu_vendor(char* cpu_vendor, unsigned int* cpuid_level) { unsigned int cpuid_op = 0x00000000; char vendor_name[16] = {'\0'}; struct cpuid_result result; unsigned int level = 0; vendor_name[0] = '\0'; //eax为0表示读取vendor id,一共12字节,依次在ebx、edx、ecx。 result = cpuid(cpuid_op); level = result.eax; vendor_name[0] = (result.ebx >> 0) & 0xff; vendor_name[1] = (result.ebx >> 8) & 0xff; vendor_name[2] = (result.ebx >> 16) & 0xff; vendor_name[3] = (result.ebx >> 24) & 0xff; vendor_name[4] = (result.edx >> 0) & 0xff; vendor_name[5] = (result.edx >> 8) & 0xff; vendor_name[6] = (result.edx >> 16) & 0xff; vendor_name[7] = (result.edx >> 24) & 0xff; vendor_name[8] = (result.ecx >> 0) & 0xff; vendor_name[9] = (result.ecx >> 8) & 0xff; vendor_name[10] = (result.ecx >> 16) & 0xff; vendor_name[11] = (result.ecx >> 24) & 0xff; vendor_name[12] = '\0'; strcpy(cpu_vendor, vendor_name); *cpuid_level = level; } void get_cpu_id(char* cpu_id, unsigned int* cpu_sign) { unsigned int cpuid_op = 0x00000001; struct cpuid_result result; unsigned int sign = 0, id = 0; unsigned int tmp = 0; result = cpuid(cpuid_op); sign = result.eax; id = result.edx; sprintf(cpu_id, "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", (sign >> 0) & 0xff, (sign >> 8) & 0xff, (sign >> 16) & 0xff, (sign >> 24) & 0xff, (id >> 0) & 0xff, (id >> 8) & 0xff, (id >> 16) & 0xff, (id >> 24) & 0xff); *cpu_sign = sign; } struct cpuinfo_x86 { //CPU family DWORD x86; //CPU vendor DWORD x86_vendor; //CPU model DWORD x86_model; //CPU stepping DWORD x86_step; }; // 参考IA32开发手册第2卷第3章。CPUID exa==0x01的图3-6 static inline void get_fms(struct cpuinfo_x86 *c, DWORD tfms) { c->x86 = (tfms >> 8) & 0xf; c->x86_model = (tfms >> 4) & 0xf; c->x86_step = tfms & 0xf; if (c->x86 == 0xf) c->x86 += (tfms >> 20) & 0xff; if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; } // 参考IA32开发手册第2卷第3章。CPUID exa==0x01的图3-6 void get_cpu_fms(unsigned int* family, unsigned int* model, unsigned int* stepping) { unsigned int cpuid_op = 0x00000001; struct cpuinfo_x86 c; unsigned int ver = 0; ver = cpuid_eax(cpuid_op); get_fms(&c, ver); *family = c.x86; *model = c.x86_model; *stepping = c.x86_step; } void get_cpu_name(char* processor_name) { unsigned int cpuid_op = 0x80000002; struct cpuid_result regs; char temp_processor_name[49]; char* processor_name_start; unsigned int *name_as_ints = (unsigned int *)temp_processor_name; unsigned int i; //用cpuid指令,eax传入0x80000002/0x80000003/0x80000004, //共3个,每个4个寄存器,每个寄存器4字节,故一共48字节。 //参考IA32开发手册第2卷第3章。 for (i = 0; i < 3; i++) { regs = cpuid(cpuid_op + i); name_as_ints[i * 4 + 0] = regs.eax; name_as_ints[i * 4 + 1] = regs.ebx; name_as_ints[i * 4 + 2] = regs.ecx; name_as_ints[i * 4 + 3] = regs.edx; } temp_processor_name[49] = '\0'; // 最后的字节为0,结束 processor_name_start = temp_processor_name; while (*processor_name_start == ' ') processor_name_start++; memset(processor_name, 0, 49); strcpy(processor_name, processor_name_start); } void get_address_bits(unsigned int* linear, unsigned int* physical) { unsigned int cpuid_op = 0x80000008; unsigned int tmp = 0; tmp = cpuid_eax(cpuid_op); *linear = (tmp >> 8) & 0xff; *physical = (tmp >> 0) & 0xff; } char* WindowsGetCpuVendorId(){ char* vendor_id; vendor_id = (char *)malloc(49); char buffer[49] = { '\0' }; unsigned int num = 0; memset((void *)buffer, '\0', sizeof(buffer)); get_cpu_vendor(buffer,&num); strcpy(vendor_id, buffer); return vendor_id; } char* WindowsGetCpuId(){ char* id; id = (char *)malloc(49); char buffer[49] = { '\0' }; unsigned int num = 0; memset((void *)buffer, '\0', sizeof(buffer)); get_cpu_id(buffer,&num); strcpy(id, buffer); return id; } char* WindowsGetCpuName(){ char* name; name = (char *)malloc(100); get_cpu_name(name); return name; } double FileTimeToDouble(FILETIME* pFiletime) { return (double)((*pFiletime).dwHighDateTime * 4.294967296E9) + (double)(*pFiletime).dwLowDateTime; } double m_fOldCPUIdleTime; double m_fOldCPUKernelTime; double m_fOldCPUUserTime; BOOL Initialize() { FILETIME ftIdle, ftKernel, ftUser; BOOL flag = FALSE; if (flag = GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) { m_fOldCPUIdleTime = FileTimeToDouble(&ftIdle); m_fOldCPUKernelTime = FileTimeToDouble(&ftKernel); m_fOldCPUUserTime = FileTimeToDouble(&ftUser); } return flag; } //获取cpu使用 int GetCPUUseRate() { int nCPUUseRate = -1; FILETIME ftIdle, ftKernel, ftUser; if (GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) { double fCPUIdleTime = FileTimeToDouble(&ftIdle); double fCPUKernelTime = FileTimeToDouble(&ftKernel); double fCPUUserTime = FileTimeToDouble(&ftUser); nCPUUseRate= (int)(100.0 - (fCPUIdleTime - m_fOldCPUIdleTime) / (fCPUKernelTime - m_fOldCPUKernelTime + fCPUUserTime - m_fOldCPUUserTime)*100.0); m_fOldCPUIdleTime = fCPUIdleTime; m_fOldCPUKernelTime = fCPUKernelTime; m_fOldCPUUserTime = fCPUUserTime; } return nCPUUseRate; } //获取cpu使用 int cpu() { if (!Initialize()) { getch(); return -1; } else { Sleep(1000); return GetCPUUseRate(); } return -1; } */ import "C" import ( "log" "unsafe" ) //获取cpu的VendorId func GetCpuVendorId() string { //定义一个字符串指针接收C 函数返回值 var out *C.char = C.WindowsGetCpuVendorId() //释放这个指针 前提是使用了malloc defer C.free(unsafe.Pointer(out)) return C.GoString(out) } //获取cpu的 CpuId func GetCpuId() string { var out *C.char = C.WindowsGetCpuId() defer C.free(unsafe.Pointer(out)) return C.GoString(out) } //获取cup的 CpuName func GetCpuName() string { var out *C.char = C.WindowsGetCpuName() defer C.free(unsafe.Pointer(out)) return C.GoString(out) } //获取cpu使用率 func GetCPUUse() int { return int(C.cpu()) } func main() { log.Println("CPU ID : ", GetCpuId()) log.Println("CPU VendorId : ", GetCpuVendorId()) log.Println("CPU Name : ", GetCpuName()) log.Println("CPU Use : ", GetCPUUse()) } ``` ## 关注ManGe分享更多知识 https://github.com/mangenotwork ![图片1.png](https://static.studygolang.com/201229/238c3089d3d64182dd55c3911ef5a543.png)![图片1.png](https://static.studygolang.com/201229/238c3089d3d64182dd55c3911ef5a543.png)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1085 次点击  
加入收藏 微博
上一篇:2020-12-29
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传