douzhong5902 2016-05-22 19:34
浏览 10
已采纳

执行:不阻止操作时根据信号采取行动

I want to fire the ps command continuously in a goroutine to monitor mem and cpu usages. I didn't use top because top doesn't allow me to select columns as ps does. This goroutine needs to receive a stop signal to stop the command, but I don't know how not to block running the command while waiting the signal. For top I can do:

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

But for ps if I do:

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

The above code will block on stop. I want to keep firing ps.Run(), while being able to stop when a stop signal is ready. Thanks.

  • 写回答

2条回答 默认 最新

  • douxiajiao8445 2016-05-22 19:59
    关注

    One way that you could achieve this is by utilizing the for/select timeout idiom, there are a couple of similar methods of doing this. Take this trivial example:

    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{}{}
    }
    

    To modify this example to work in your circumstance place the code that you want to run in the <-time.After(): case, which (in this instance) will run once per second, if no other case is available to receive for that duration. And instead of time.Sleep() which I placed at the end, put the code that will interrupt the <-time.After(): case, sending <- struct{}{} on the abort channel (or whatever you name it).

    NOTE: In an earlier version of this answer I had abort as a chan bool, as I like the clarity of <-abort true and don't consider chan struct{} to be as clear, I opted to change it in this example however, as <- struct{}{} isn't unclear, especially once you've gotten used to the pattern.

    Also, if you want the command to execute on each iteration of the for loop and not wait for a timeout then you can make that case default:, remove <-time.After() and it will run on each iteration of the loop where another channel is not ready to receive.

    You can play with this example in the playground if you'd like, although it will not allow syscalls, or the default: case example to be run in that environment.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c