douchanxiu5636 2018-07-14 12:45
浏览 53

等到条件满足或超时

I'm trying to write a function that break when a condition is met the output of command is equal something (hello in this example) in this case or timeout is reached

timeout := 10 sec

func run() error {

for {

    out , _ := exec.Command("echo", "hello").Output()
    if string(out) == "hello" || timeout  {
        break
    }
}

}

I've seen that folks use select but I don't know how to use it here, any hints?

  • 写回答

2条回答 默认 最新

  • dtsc14683 2018-07-14 12:50
    关注

    You can use a similar code than Go by Example: Timeouts

    c2 := make(chan string, 1) 
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "result 2"
    }()
    select {
    case res := <-c2:
        fmt.Println(res)
    case <-time.After(3 * time.Second):
        fmt.Println("timeout 2")
    }
    

    In your case, the go func would exec the echo, while the main function would wait for a timeout, or the execution of go func, whichever comes first.

    That is: https://goplay.space/#MtHh3CenMcn

    package main
    
    import (
        "fmt"
        "os/exec"
        "time"
    )
    
    func main() {
        c2 := make(chan string, 1)
        go func() {
            out, err := exec.Command("echo", "hello").Output()
            fmt.Println(err)
            c2 <- string(out)
        }()
        select {
        case res := <-c2:
            fmt.Println("'" + res + "'")
        case <-time.After(3 * time.Second):
            fmt.Println("timeout 2")
        }
    }
    

    If the echo takes more than 3 seconds, the timeout would kick in.

    Note that the example does not work i a playground setting, because:

    "echo": executable file not found in $PATH
    

    But in your local environment, it should work.


    A different approach, based on context: https://goplay.space/#F2GtMLgVAAI

    package main
    
    import (
        "context"
        "fmt"
        "os/exec"
    )
    
    func main() {
        gen := func(ctx context.Context) <-chan string {
            dst := make(chan string)
            go func() {
                out, err := exec.Command("echo", "hello").Output()
                fmt.Println(err)
                for {
                    select {
                    case <-ctx.Done():
                        return // returning not to leak the goroutine
                    case dst <- string(out):
                        return
                    }
                }
            }()
            return dst
        }
    
        ctx, cancel := context.WithTimeout(context.Background(), 3)
    
        defer cancel() // cancel when we are finished consuming integers
        gen(ctx)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)