使用Golang获取Linux系统的赫兹频率

使用Golang获取Linux系统的赫兹频率 如何使用 Go 语言获取 Linux 系统的赫兹值? 是否有可以直接获取赫兹值的相关包?

19 回复

我自己写的

更多关于使用Golang获取Linux系统的赫兹频率的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢您提供的有用信息 😊

我可以将所有CPU的频率相加来计算总CPU频率吗?

是的,我们是同学,而且我们两个都是Go语言的初学者。

我不太明白,能否请你给我展示一个代码示例?

谢谢 我会学习这些章节的Go教程

&Unixprocess{pid:pid}

这是什么意思?

&Unixprocess{pid:pid}

不。输出告诉我我的计算机有四个核心,每个核心频率为800 MHz。

但这与Go语言编程有什么关系呢?

那么你应该知道 p 是什么。

我的印象是你和 @Socrates27 提出了非常相似的问题。你们是在同一家公司工作,还是需要完成相同的课堂作业?

在Go库中搜索不到Unixprocess。您是通过导入哪个库获取它的?还是您自己编写的?

你是如何使用 Go 实现这个功能的?请展示你尝试过的代码。它能正常工作吗?如果无法运行,请告诉我们具体情况:是否出现错误?结果是否符合预期?

这些信息可以从 /proc/cpuinfo 中获取。在 bash 中:

$ cat /proc/cpuinfo | grep "cpu MHz"
cpu MHz         : 800.000
cpu MHz         : 800.000
cpu MHz         : 800.000
cpu MHz         : 800.000

你学过Go语言教程吗?其中包含了关于指针结构体字面量的章节。这两个概念适用于:

&Unixprocess{pid:pid}

给我一点时间,如果出现问题我会展示代码

现在你能解释一下这个函数吗

func newUnixProcess(pid int) ( *Unixprocess, error){
	p := &Unixprocess{pid:pid}
	return p, p.Refresh()
}

这里Unixprocess是结构体,Refresh()是另一个函数 变量p代表什么?

我想在Linux系统中查找每个正在运行的进程的CPU使用情况
并且我找到了一个公式:https://stackoverflow.com/questions/16726779/how-do-i-get-the-total-cpu-usage-of-an-application-from-proc-pid-stat

我正在使用GO语言来提取这些信息

那个 Stack Overflow 帖子中提到的 “Hertz” 与 CPU 频率不同。

该帖子讨论的是时钟内部分辨率,你需要按照帖子中提到的方法使用 CLI 工具 getconf 来查询系统。对于 C 语言,帖子还提到了一个替代的函数调用方法。

我不确定是否有该函数的绑定可用,所以我会直接使用 os/exec 来执行 getconf CLK_TCK 并解析其输出。

目前我看不到从 Go 内部获取所需信息的其他方法。

func main() {
    // 使用 os/exec 执行 getconf CLK_TCK
    cmd := exec.Command("getconf", "CLK_TCK")
    output, err := cmd.Output()
    if err != nil {
        log.Fatal(err)
    }
    // 解析输出
    fmt.Println(string(output))
}

根据我的Debian系统手册页说明,虽然CLK_TCK仍然可用,但现已过时。我可以运行getconf命令并获得正确答案:

$ getconf CLK_TCK
100

(现代Linux系统通常每秒100个时钟滴答。)

以下是使用Go(实际上是cgo)从Linux系统获取每秒时钟滴答数的非过时方法,滴答数将存储在变量"hz"中:

package main

/*
#include <unistd.h>

long sysconf(int name);

static long gethz(void)
{
        return sysconf(_SC_CLK_TCK);
}
*/
import "C"
import "fmt"

func main() {
        hz := C.gethz()
        fmt.Printf("%v clock ticks per second\n",hz)
}

这实际上只是对调用sysconf() C库函数的C程序的封装。有关我如何创建此代码的详细信息,请参阅sysconf(3)手册页和cgo文档。

虽然这比实际需要的更复杂,但它比以下更简洁的方式更能清楚地展示整个过程:

package main

/* #include <unistd.h> */
import "C"
import "fmt"

func main() {
        hz := C.sysconf(C._SC_CLK_TCK)
        fmt.Printf("%v clock ticks per second\n",hz)
}

类似这样的代码:

package main

import (
	"bytes"
	"fmt"
	"os/exec"
)

func main() {
	cmd := exec.Command("getconf", "CLK_TCK")
	out := new(bytes.Buffer)
	cmd.Stdout = out
	_ = cmd.Run()
	fmt.Printf("CLK_TCK: %v", out.String())
}

当然你应该在代码周围添加一些错误处理,并且需要正确解析out的内容,将其转换为整数才能实际使用。

但这是你需要走的方向。

另外,未来你们(两位)应该在提问时多下点功夫。

正如你们在这个讨论中已经了解到的,"Linux系统的赫兹"可能指代很多不同的概念:

  1. 最大CPU频率(通常所有核心都相同)
  2. 当前CPU频率(在现代系统中每个核心可能不同)
  3. 内核时钟分辨率(这是本讨论中你实际想了解的)
  4. 系统中各种硬件总线的频率
  5. 显示器的刷新率(可能有多个显示器且刷新率不同)
  6. 可能还有其他含义

所以从一开始就更具体地说明会对你们更有帮助。

即使在你提供了Stack Overflow的链接之后,关于你实际想要实现的目标仍然存在一些困惑,你仍然被引导到了错误的方向。

这是因为很多人并不会仔细阅读那些链接,只是粗略浏览,他们认为已经做了深入的阅读和研究。

此外,你和你的朋友经常只发布一些代码片段,这些片段在第一眼和第二眼看起来似乎与问题无关。或者它们缺乏必要的上下文来理解。

请不要误会,我真的很乐意帮忙,但我更希望看到提问的人首先做好了功课,而不是想要一些现成的、完美的代码,可以在学期末直接上交……

在Go语言中,可以通过读取Linux系统的/proc文件系统来获取系统的赫兹频率(Hertz,通常为100 Hz)。具体来说,可以解析/proc/stat文件中的jiffies值,或者直接使用系统调用获取CLK_TCK值。以下是两种方法的示例代码:

方法一:通过读取/proc/stat获取Hertz值

在Linux系统中,/proc/stat文件包含了系统启动以来的jiffies计数,而Hertz值通常为100(即每秒100个jiffies)。你可以通过计算单位时间内的jiffies变化来间接获取,但更简单的是直接使用标准值100。如果需要动态获取,可以解析系统信息。

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
)

// 获取系统Hertz值,默认为100
func getHertz() int {
    // 在大多数Linux系统中,Hertz值固定为100
    return 100
}

func main() {
    hertz := getHertz()
    fmt.Printf("System Hertz value: %d\n", hertz)
}

方法二:使用系统调用获取CLK_TCK

CLK_TCK是系统时钟滴答频率,通常与Hertz值相同。可以通过sysconf系统调用获取,但Go标准库没有直接封装。可以使用golang.org/x/sys/unix包进行系统调用。

首先,安装golang.org/x/sys/unix包:

go get golang.org/x/sys/unix

然后,使用以下代码:

package main

import (
    "fmt"
    "golang.org/x/sys/unix"
)

func getHertz() (int, error) {
    // 使用sysconf获取_CLK_TCK
    hertz, err := unix.Sysconf(unix.SC_CLK_TCK)
    if err != nil {
        return 0, err
    }
    return int(hertz), nil
}

func main() {
    hertz, err := getHertz()
    if err != nil {
        fmt.Printf("Error getting Hertz: %v\n", err)
        return
    }
    fmt.Printf("System Hertz value: %d\n", hertz)
}

说明

  • 在大多数Linux系统上,Hertz值固定为100,因此直接返回100是安全的。
  • 如果需要精确值,推荐使用方法二,它通过系统调用获取CLK_TCK,确保兼容性。
  • 没有专门的Go包直接提供Hertz值,但上述方法可靠且高效。

运行代码后,将输出系统的Hertz频率值。例如:

System Hertz value: 100
回到顶部