zoukankan      html  css  js  c++  java
  • golang context 超时自动取消方法

    WithTimeout 超时自动取消方法,当执行一个go 协程时,超时自动取消协程

    package main
    
    import (
      "fmt"
      "time"
      "context"
    )
    
    var res int
    
    // 模拟一个最小执行时间的阻塞函数
    func inc(a int) int {
        res = a + 1                // 虽然我只做了一次简单的 +1 的运算,
        time.Sleep(10 * time.Second) // 但是由于我的机器指令集中没有这条指令,
        // 所以在我执行了 1000000000 条机器指令, 续了 1s 之后, 我才终于得到结果。B)
        return res
    }
    
    // 向外部提供的阻塞接口
    // 计算 a + b, 注意 a, b 均不能为负
    // 如果计算被中断, 则返回 -1
    func Add(ctx context.Context, a, b int) int {
        res = 0
        go inc(res) //要是协程
        for {
            select {
            case <-ctx.Done():
                fmt.Println("ctx Done in a")
                return -1
            default:
            }
        }
        for i := 0; i < b; i++ {
            res = inc(res)//执行完才会走到select中
            select {
            case <-ctx.Done():
                fmt.Println("ctx Done in b")
                return -1
            default:
            }
        }
        return res
    }
    
    func main() {
        // 使用开放的 API 计算 a+b
        a := 1
        b := 2
        timeout := 1000 * time.Millisecond
        ctx, cancel := context.WithTimeout(context.Background(), timeout)
        defer cancel()
        res := Add(ctx, 1, 2)
        fmt.Printf("Compute: %d+%d, result: %d
    ", a, b, res)
    }
    
    

    在使用golang开发中,调用外部可执行程序通过exec包是我们常用的方式。如何控制超时请见如下代码:

    func CmdWithTimeout(name string, arg ...string) ([]byte, error) {
        //timeout 的值可以放在环境变量里
        timeoutstr, err := strconv.Atoi(os.Getenv("cmd-timeout"))
        if err != nil {
    	log.Errorf("fail to load netlink timeout: %v", err)
    	return nil, err
        }
        timeoutval := time.Duration(timeoutstr) * time.Millisecond
    
        ctxt, cancel := context.WithTimeout(context.Background(), timeoutval)
        defer cancel()
    
        cmd := osexec.CommandContext(ctxt, name, arg...)
    
        var ret []byte
        ret, err = cmd.CombinedOutput()
        return ret, err
    }
    

    需要搭配接收ctx.Done()消息,超时才能退出。

  • 相关阅读:
    概率图模型 ——(6)团树传播算法
    概率图模型 ——(5)变量消元法求边缘概率
    Catkin workspace `/home/qian` is already initialized. No action taken.
    安装TensorRT
    vscode教程
    概率图模型 ——(4)因子图
    概率图模型 ——(3)马尔科夫随机场
    概率图模型 ——(2)贝叶斯网络
    概率图模型 ——(1)概率论与图论基础
    Kubernetes 是怎么实现服务发现的?
  • 原文地址:https://www.cnblogs.com/janeysj/p/12809659.html
Copyright © 2011-2022 走看看