• Go Context


    Context

    介绍

    // Context 代表了协程的上下文,用以在父子协程之间传递控制信号,共享变量等操作
    
    // context.Context 接口
    type Context interface {
    	// 当Context自动取消或者到了取消时间被取消后返回
    	Deadline() (deadline time.Time, ok bool)
    	// 当Context被取消或者到了deadline返回一个被关闭的channel
    	Done() <-chan struct{}
    	// 当Context被取消或者关闭后,返回context取消的原因
    	Err() error
    	// 获取 Context 中保存的键值对数据
    	Value(key any) any
    }
    
    

    使用 WithValue() 传递数据

    func A(ctx context.Context) context.Context {
    	time.Sleep(1 * time.Second)
    	fmt.Println("A: ", ctx.Value("main"))
    	ctx = context.WithValue(ctx, "A", "A-1")
    	go B(ctx)
    	return ctx
    }
    
    func B(ctx context.Context) context.Context {
    	time.Sleep(1 * time.Second)
    	fmt.Println("B: ", ctx.Value("main"))
    	fmt.Println("B: ", ctx.Value("A"))
    	return ctx
    }
    
    func main() {
    	ctx := context.WithValue(context.Background(), "main", "main-1")
    	go A(ctx)
    	time.Sleep(3 * time.Second)
    }
    

    使用 WithCancel() 取消操作

    func main() {
    	ctx, cancel := context.WithCancel(context.Background())
    	go Speak(ctx)
    	time.Sleep(3 * time.Second)
    	cancel()
    	time.Sleep(1 * time.Second)
    }
    
    func Speak(ctx context.Context) {
    	for range time.Tick(time.Second) {
    		select {
    		case <-ctx.Done():
    			fmt.Println("我要闭嘴了")
    			return
    		default:
    			fmt.Println("balabalabalabala")
    		}
    	}
    }
    

    使用 WithDeadline() 设置截止时间

    使用 WithTimeout() 设置超时时间

    withTimeout和withDeadline作用是一样的,就是传递的时间参数不同,会通过传入的时间来自动取消Context,都会返回一个cancelFunc方法,通过调用这个方法可以达到提前进行取消
    使用的过程还是建议在自动取消后也调用cancelFunc去停止定时减少不必要的资源浪费
    
    func A(in chan struct{}) {
    	time.Sleep(1 * time.Second)
    	in <- struct{}{}
    }
    
    func B(in chan struct{}) {
    	time.Sleep(3 * time.Second)
    	in <- struct{}{}
    }
    
    func main() {
    	var ch1 = make(chan struct{})
    	var ch2 = make(chan struct{})
    	var ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
    
    	go func() {
    		go A(ch1)
    		select {
    		case <-ctx.Done():
    			fmt.Println("ctx timeout")
    			break
    		case <-ch1:
    			fmt.Println("A Done")
    		}
    	}()
    
    	go func() {
    		go B(ch2)
    		select {
    		case <-ctx.Done():
    			fmt.Println("ctx timeout")
    			break
    		case <-ch2:
    			fmt.Println("B Done")
    		}
    	}()
    	defer cancel()
    	time.Sleep(5 * time.Second)
    }
    
  • 相关阅读:
    微软和OpenAI正在开发AI芯片, 并计划下个月发布
    基于SpringBoot的实习管理系统
    GB/T28181-2016 SDP定义和音视频传输模式解读
    基于 Webpack5 Module Federation 的业务解耦实践
    简述CRM系统软件的作用
    【牛客刷题-SQL大厂面试真题】NO1.某音短视频
    ASP.NET Core使用记录3
    路由过滤与引入
    【微信小程序】运行机制和更新机制
    利用FME读取Word中的表格
  • 原文地址:https://blog.csdn.net/qq_43157273/article/details/139810334