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()消息,超时才能退出。

  • 相关阅读:
    HDU 1847
    HDU 1717
    KMP未优化模板、
    Codeforces Round #340 (Div. 2) B. Chocolate
    HDU 1042 N!
    HDU 1018 Big Number
    HDU 1031 Design T-Shirt
    解决Windows 7删除执行过的 EXE、Bat文件有延迟的问题
    修改Android手机的“虚拟机堆大小”和android:largeHeap来防止APP内存溢出问题
    Android引用百度定位API第三方组件后导致其它.so文件无法正常加载的问题
  • 原文地址:https://www.cnblogs.com/janeysj/p/12809659.html
Copyright © 2011-2022 走看看