Golang中如何使用自启动以来的单调时钟
Golang中如何使用自启动以来的单调时钟 大家好,
我正在开发一个专门用于在不同传感器之间进行测量的Go语言代码。每个传感器都有自己的代码,我希望能够在板上实现一个统一的计时基准。所有传感器都由一个树莓派管理。因此,我需要一个非常精确的时钟,为不同的代码提供一个共同的起始点。过去我使用C++开发这些代码时,使用的是steady_clock(链接),它是一个单调且精确的时钟(微秒级),从系统启动开始计时。现在我正在使用Go语言进行开发,正在寻找一个等效的方法。你们知道如何实现吗?
提前感谢!!
更多关于Golang中如何使用自启动以来的单调时钟的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang中如何使用自启动以来的单调时钟的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中,你可以使用time.Since(bootTime)结合系统启动时间来实现类似C++ steady_clock的功能。以下是具体实现:
package main
import (
"fmt"
"time"
"syscall"
)
var bootTime time.Time
func init() {
// 获取系统启动时间(Linux系统)
var sysinfo syscall.Sysinfo_t
err := syscall.Sysinfo(&sysinfo)
if err != nil {
panic(err)
}
bootTime = time.Now().Add(-time.Duration(sysinfo.Uptime) * time.Second)
}
// MonotonicClock 返回自系统启动以来的单调时间
func MonotonicClock() time.Duration {
return time.Since(bootTime)
}
func main() {
// 示例:获取自启动以来的精确时间
t1 := MonotonicClock()
time.Sleep(100 * time.Millisecond)
t2 := MonotonicClock()
fmt.Printf("启动后时间1: %v\n", t1)
fmt.Printf("启动后时间2: %v\n", t2)
fmt.Printf("时间差: %v\n", t2-t1)
// 微秒级精度输出
fmt.Printf("时间差(微秒): %d μs\n", (t2-t1).Microseconds())
}
对于需要更高精度和跨平台兼容性的情况,可以使用runtime.nanotime():
package main
import (
"fmt"
"time"
"unsafe"
)
//go:linkname nanotime runtime.nanotime
func nanotime() int64
func MonotonicNanoseconds() int64 {
return nanotime()
}
func main() {
start := MonotonicNanoseconds()
time.Sleep(150 * time.Microsecond)
end := MonotonicNanoseconds()
elapsed := end - start
fmt.Printf("耗时: %d ns\n", elapsed)
fmt.Printf("耗时: %.3f μs\n", float64(elapsed)/1000)
}
如果你需要与C++ steady_clock完全相同的纳秒级单调时钟,可以使用cgo调用系统时钟:
package main
/*
#include <time.h>
static long long steady_clock_ns() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (long long)ts.tv_sec * 1000000000LL + (long long)ts.tv_nsec;
}
*/
import "C"
import "fmt"
func SteadyClock() int64 {
return int64(C.steady_clock_ns())
}
func main() {
t1 := SteadyClock()
// 模拟工作负载
for i := 0; i < 1000; i++ {}
t2 := SteadyClock()
fmt.Printf("CLOCK_MONOTONIC时间: %d ns\n", t2-t1)
}
第一种方法适合大多数应用场景,精度在微秒级。第二种方法提供了纳秒级精度但需要Go的内部链接。第三种方法通过cgo直接调用系统CLOCK_MONOTONIC,与C++的steady_clock行为完全一致。

