Go超时(timeouts)实例

超时对于连接到外部资源或在不需要绑定执行时间的程序很重要。在Go编程中由于使用了通道和选择(select),实现超时是容易和优雅的。
在这个示例中,假设正在执行一个外部调用,2秒后在通道c1上返回其结果。

这里是 select 实现超时。 res:= <-c1等待结果和<-Time。等待在超时1秒后发送一个值。 由于选择继续准备好第一个接收,如果操作超过允许的1秒,则将按超时情况处理。

如果允许更长的超时,如:3s,那么从c2的接收将成功,这里将会打印结果。

运行此程序显示第一个操作超时和第二个操作超时。

使用此选择超时模式需要通过通道传达结果。这是一个好主意,因为其他重要的Go功能是基于渠道和Select。现在看看下面的两个例子:计时器和ticker

所有的示例代码,都放在 F:\worksp\golang 目录下。安装Go编程环境请参考:http://www.yiibai.com/go/go_environment.html

timeouts.go的完整代码如下所示 -



package main

import "time"
import "fmt"

func main() {

    // For our example, suppose we're executing an external
    // call that returns its result on a channel `c1`
    // after 2s.
    c1 := make(chan string, 1)
    go func() {
        time.Sleep(time.Second * 2)
        c1 <- "result 1"
    }()

    // Here's the `select` implementing a timeout.
    // `res := <-c1` awaits the result and `<-Time.After`
    // awaits a value to be sent after the timeout of
    // 1s. Since `select` proceeds with the first
    // receive that's ready, we'll take the timeout case
    // if the operation takes more than the allowed 1s.
    select {
    case res := <-c1:
        fmt.Println(res)
    case <-time.After(time.Second * 1):
        fmt.Println("timeout 1")
    }

    // If we allow a longer timeout of 3s, then the receive
    // from `c2` will succeed and we'll print the result.
    c2 := make(chan string, 1)
    go func() {
        time.Sleep(time.Second * 2)
        c2 <- "result 2"
    }()
    select {
    case res := <-c2:
        fmt.Println(res)
    case <-time.After(time.Second * 3):
        fmt.Println("timeout 2")
    }
}

F : \worksp\golang > go run timeouts . go
timeout
1
result
2
实例
	//test if the rtmp stream is ok at first
	//getChArg := "ffprobe -i rtmp://1.31.159.208:10040/live/seq_4002 -show_streams 2>> /dev/null  |grep channels"
	//getChArg := "ffprobe -i " + rtmpUrl + "  -show_streams 2>> /dev/null  |grep channels"

	c2 := make(chan string, 1)
	go func() {
		arg := "ffprobe -i " + rtmpUrl + "  -show_streams 2>> /dev/null  |grep channels"

		cmd := exec.Command("/bin/sh", "-c", arg)
		out, err := cmd.Output()
		if err != nil {
			log.Warn(err.Error())
		}
		log.Debug("check stream cmd: %s, channes info :%s", arg, string(out))
		if true == strings.Contains(string(out), "channels") {
			log.Info("normal stream")
		}

		c2 <- "stream ok"
	}()
	select {
	case res := <-c2:
		log.Debug(res)
	case <-time.After(time.Second * 4):
		log.Warn("timeout 4s")
		outM = &outMessage{
			NOK_PULL_COMMAND,
			"fail to get stream info, please check if stream is pushed ok",
		}
		b, err := json.Marshal(outM)
		if err != nil {
			log.Fatal("json encode message failed")
			w.Write([]byte("{\"result\":-10,\"message\":\"encode resp message error\"}"))
		} else {
			w.Write([]byte(string(b)))
		}
		panic(err)
		return
	}

 

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值