gpt4 book ai didi

Go:在不阻塞操作的情况下根据信号采取行动

转载 作者:IT王子 更新时间:2023-10-29 01:42:08 27 4
gpt4 key购买 nike

我想在 goroutine 中连续触发 ps 命令来监控内存和 cpu 使用情况。我没有使用 top,因为 top 不允许我像 ps 那样选择列。这个 goroutine 需要接收停止信号来停止 command,但我不知道如何在等待信号时不阻止运行命令。对于 top 我可以这样做:

top := exec.Command("top")
<-stop // blocking
top.Process.Signal(os.Kill)

但是对于 ps 如果我这样做:

ps := exec.Command("ps")
for {
ps.Run()
<-stop
}

上面的代码将在 stop 时阻塞。我想继续触发 ps.Run(),同时能够在停止信号准备就绪时停止。谢谢。

最佳答案

实现此目的的一种方法是使用 for/select timeout 习惯用法,有几种类似的方法可以做到这一点。以这个简单的例子为例:

package main

import (
"fmt"
"time"
)

func main() {
abort := make(chan struct{})

go func() {
for {
select {
case <-abort:
return
case <-time.After(1 * time.Second):
// replace fmt.Println() with the command you wish to run
fmt.Println("tick")
}
}
}()
// replace time.Sleep() with code waiting for 'abort' command input
time.Sleep(10 * time.Second)
abort <- struct{}{}
}

要修改此示例以在您的环境中工作,请将要运行的代码放在 <-time.After(): 中case,如果在此期间没有其他 case 可接收,则(在本例中)将每秒运行一次。而不是 time.Sleep()我放在最后的代码会中断 <-time.After():案例,发送<- struct{}{}abort 上 channel (或任何你命名的 channel )。

注意:在这个答案的早期版本中,我已经中止为 chan bool ,因为我喜欢 <-abort true 的清晰度并且不考虑chan struct{}明确地说,我选择在此示例中将其更改为 <- struct{}{}不清楚,尤其是在您习惯了这种模式之后。

此外,如果您希望命令在 for 循环的每次迭代中执行而不是等待超时,那么您可以使用 default: , 删除 <-time.After()它将在循环的每次迭代中运行,其中另一个 channel 尚未准备好接收。

您可以在 playground 中使用此示例如果你愿意,尽管它不允许系统调用,或者 default:在该环境中运行的案例。

关于Go:在不阻塞操作的情况下根据信号采取行动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37378775/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com