防止Golang后台进程占用过多的CPU资源

问题描述 投票:0回答:1

我正在编写一个Go程序,该程序监视文件并在其中一个文件已更改的情况下运行系统命令。到目前为止,它运行良好。我对主“无限”循环有疑问,因为我不想让它占用所有系统CPU资源:

runtime.GOMAXPROCS(1)
for {
    updatedFiles, _ := GetWatchMap(config)
    if !reflect.DeepEqual(filesToWatch, updatedFiles) {
        start := time.Now()
        _, _ = colorstring.Println(fmt.Sprintf(" [yellow] ⬇ Update detected[white] at [green]%s[white] > updating...", start.Format("15:04:05")))
        _, _ = Update(config)
        end := time.Now()
        elapsed := end.Sub(start)
        _, _ = colorstring.Println(fmt.Sprintf("  [green]✅  Done![white] in [yellow]%.2f[white] second(s).", elapsed.Seconds()))
        filesToWatch = updatedFiles
    } else {
        time.Sleep(config.SleepTime)
    }
}

因此,我所做的是设置GOMAXPROCS,因此它仅使用“ 1 CPU / Core”,并且我在else分支中添加了可配置的睡眠时间。

[如果没有调用runtime.GOMAXPROCS(1),无论是否调用,htop都会显示该进程占用100%的CPU时间(我猜它是一个内核的100%?)。

如果我在计算机(MacMini i7,12核)上使用30ms的睡眠时间,则htop报告该进程的CPU利用率为20%,这似乎还可以,但是我猜这会因运行该程序的计算机而异。

这里的最佳做法是什么?

go process cpu-usage htop
1个回答
3
投票

GOMAXPROCS并非您认为的那样。从程序包运行时文档中:

GOMAXPROCS变量限制了可以同时执行用户级Go代码的操作系统线程的数量。对于代表Go代码的系统调用中可以阻止的线程数量没有限制;那些不计入GOMAXPROCS限制。

它限制了操作系统线程。如果您的代码不使用goroutines,则could会被安排到OS线程中,因此实际上限制了线程的数量是[[nothing。只需删除GOMAXPROCS内容,它什么也不会做。 (如果将GOMAXPROCS设置为12,则实际上最多有12个OS线程实际在执行goroutine代码;如果只有一个goroutine限制了可以在其上运行的OS线程的数量,则为noop。)

您所能做的就是不像使用time.Sleep()那样忙循环。根据

您的

要求,您可以定期调用实际代码,例如通过时间。没有单一的“最佳实践”(例外不喜欢GOMAXPROCS)。
© www.soinside.com 2019 - 2024. All rights reserved.