4

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

 3 years ago
source link: https://studygolang.com/articles/32390
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

漫鸽 · 大约10小时之前 · 41 次点击 · 预计阅读时间 7 分钟 · 不到1分钟之前 开始浏览    

238c3089d3d64182dd55c3911ef5a543.png
图片1.png
  1. 调用汇编 cpuid指令
  2. 调用 windows.h 的 GetSystemTimes
  1. malloc开辟的空间要在使用结束后用free回收,具体写法如下代码
// 代码出处我的开源项目: 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


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

280

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK