golang context 超时自动取消方法

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

package main

import (
  "fmt"
  "time"
  "context"
)

func main() {
    ctx, _ := context.WithTimeout(context.Background(), 5 * time.Second)
    fmt.Println("start at ", time.Now().Format("2006-01-02 15:04:05"))
    go func() {
        defer func() {
            fmt.Println("goroutine exit ", time.Now().Format("2006-01-02 15:04:05"))
        }()

        for {
            select {
            case <-ctx.Done():  // 因为ctx带超时参数,当时间期限到了之后就会走到这里退出协程
                fmt.Println("Done. ", time.Now().Format("2006-01-02 15:04:05"))
                return
            default:            // 协程循环执行for,当ctx.Done()无信号时总是走到Default分支
                fmt.Println("case default ", time.Now().Format("2006-01-02 15:04:05"))
                time.Sleep(time.Second)
            }
        }
    }()

    time.Sleep(20 * time.Second) // 主程序用sleep阻塞住
    fmt.Println("stop at ", time.Now().Format("2006-01-02 15:04:05"))
}

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

posted @   JaneySJ  阅读(8706)  评论(2编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示