为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
千万里不及你 2022-01-10 18:50:07
我想ps在 goroutine 中连续触发命令来监控内存和 cpu 的使用情况。我没有使用,top因为top不允许我像ps那样选择列。这个goroutine需要接收一个停止信号来停止command,但我不知道如何在等待信号时不阻止运行命令。因为top我可以这样做:top := exec.Command("top")<-stop // blockingtop.Process.Signal(os.Kill)但ps如果我这样做:ps := exec.Command("ps")for {    ps.Run()    <-stop}上面的代码将阻塞在stop. 我想继续射击ps.Run(),同时能够在停止信号准备好时停止。谢谢。
查看完整描述

2 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

实现此目的的一种方法是利用 for/select 超时习语,有几种类似的方法可以做到这一点。举个简单的例子:


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():案例中,如果在此期间没有其他案例可接收,则该案例(在此实例中)将每秒运行一次。而不是time.Sleep()我放在最后的代码,而是放置将中断<-time.After():案例的代码, <- struct{}{}在abort通道上发送(或任何你命名的)。


注意:在这个答案的早期版本中,我中止了一个chan bool,因为我喜欢它的清晰性<-abort true并且不认为 chan struct{}它很清晰,但是我选择在这个例子中改变它,因为<- struct{}{}不清楚,特别是一旦你已经习惯了这种模式。


此外,如果您希望命令在 for 循环的每次迭代中执行并且不等待超时,那么您可以设置 case default:, remove<-time.After()并且它将在另一个通道尚未准备好接收的循环的每次迭代中运行。


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


查看完整回答
反对 回复 2022-01-10
?
茅侃侃

TA贡献1842条经验 获得超22个赞

在不睡觉的情况下一遍又一遍地运行它:


func run(stop <-chan struct{}) {

    ps := exec.Command("ps")

    for {

        select {

        case <-stop:

            return

        default:

            ps.Run()

            //processing the output

        }

    }

}

然后go run(stop)。并每 3 秒运行一次(例如):


func run(stop <-chan struct{}) {

    ps := exec.Command("ps")

    tk := time.Tick(time.Second * 3)

    for {

        select {

        case <-stop:

            return

        case <-tk:

            ps.Run()

            //processing the output

        }

    }

}


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 179 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号