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

我想ps在 goroutine 中连续触发命令来监控内存和 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(),同时能够在停止信号准备好时停止。谢谢。


千万里不及你
浏览 180回答 2
2回答

蝴蝶不菲

实现此目的的一种方法是利用 for/select 超时习语,有几种类似的方法可以做到这一点。举个简单的例子:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; abort := make(chan struct{})&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case <-abort:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case <-time.After(1 * time.Second):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // replace fmt.Println() with the command you wish to run&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("tick")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; // replace time.Sleep() with code waiting for 'abort' command input&nbsp; &nbsp; time.Sleep(10 * time.Second)&nbsp; &nbsp; abort <- struct{}{}}要修改此示例以在您的情况下工作,请将您要运行的代码放在<-time.After():案例中,如果在此期间没有其他案例可接收,则该案例(在此实例中)将每秒运行一次。而不是time.Sleep()我放在最后的代码,而是放置将中断<-time.After():案例的代码, <- struct{}{}在abort通道上发送(或任何你命名的)。注意:在这个答案的早期版本中,我中止了一个chan bool,因为我喜欢它的清晰性<-abort true并且不认为 chan struct{}它很清晰,但是我选择在这个例子中改变它,因为<- struct{}{}不清楚,特别是一旦你已经习惯了这种模式。此外,如果您希望命令在 for 循环的每次迭代中执行并且不等待超时,那么您可以设置 case default:, remove<-time.After()并且它将在另一个通道尚未准备好接收的循环的每次迭代中运行。如果您愿意,您可以在操场上使用此示例,尽管它不允许系统调用或default:案例示例在该环境中运行。

茅侃侃

在不睡觉的情况下一遍又一遍地运行它:func run(stop <-chan struct{}) {&nbsp; &nbsp; ps := exec.Command("ps")&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-stop:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ps.Run()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //processing the output&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}然后go run(stop)。并每 3 秒运行一次(例如):func run(stop <-chan struct{}) {&nbsp; &nbsp; ps := exec.Command("ps")&nbsp; &nbsp; tk := time.Tick(time.Second * 3)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-stop:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; case <-tk:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ps.Run()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //processing the output&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go