• Context


    Context(context.go)

    源码中我们可以得知有 context 是一个 interface,

    type Context interface {
      Deadline() (deadline time.Time, ok bool)
      Done() <-chan struct{}
      Err() error
      Value(key any) any
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    func Background() Context
    func TODO() Context
    func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
    func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
    func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
    func WithValue(parent Context, key, val interface{}) Context
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Deadline 方法需要返回当前 Context 被取消的时间,也就是完成工作的截止时间(deadline);

    Done 方法需要返回一个 Channel,这个 Channel 会在当前工作完成或者上下文被取消之后关闭,多次调用 Done 方法会返回同一个 Channel;

    Value 方法会从 Context 中返回键对应的值,对于同一个上下文来说,多次调用 Value 并传入相同的 Key 会返回相同的结果,该方法可用于传递跨 API 和进程间跟请求域的数据;

    Background
    // Background returns a non-nil, empty Context. It is never canceled, has no
    // values, and has no deadline. It is typically used by the main function,
    // initialization, and tests, and as the top-level Context for incoming
    // requests.
    func Background() Context {
    	return background
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例代码

    func main() {
    	ctx := context.Background()
    	sleepAndTalk(ctx, 5*time.Second, "hello")
    }
    
    func sleepAndTalk(ctx context.Context, d time.Duration, msg string) {
    	select {
    	case <-ctx.Done():
    		fmt.Println("done")
    	case <-time.After(d):
    		fmt.Println(msg)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    Background()和 TODO()

    Background()常用于初始化以及测试代码,作为 top-level 的 context。

    TODO(),没有什么具体含义,但是又必须传递 ctx 的时候可以使用。

    二者的共同点都是,没有 deadling, 没有 value, 没有 cancle
    的 empty context

    WithCancle
    func main() {
    	ctx := context.Background()
    	ctx, cancle := context.WithCancel(ctx)
    	// 1. 用户输入信息后context 执行cancle, 2022-11-21-22:54 控制台输出context deadline exceeded
    	// go func() {
    	// 	s := bufio.NewScanner(os.Stdin)
    	// 	s.Scan()
    	// 	cancle()
    	// }()
    	// 2. 1s之后取消,然后控制台输出 context deadline exceeded
    	// go func() {
    	// 	time.Sleep(time.Second)
    	// 	cancle()
    	// }()
    	// 3. 或者可以使用time.afterfunc 同2方法一样效果
    	time.AfterFunc(time.Second, cancle)
    	sleepAndTalk(ctx, 5*time.Second, "hello")
    }
    
    func sleepAndTalk(ctx context.Context, d time.Duration, msg string) {
    	select {
    	case <-ctx.Done():
    		fmt.Println(ctx.Err())
    	case <-time.After(d):
    		fmt.Println(msg)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    withTimeOut
    
    func main() {
    	ctx := context.Background()
    	ctx, cancle := context.WithTimeout(ctx, time.Second)
    	defer cancle()
    	sleepAndTalk(ctx, 5*time.Second, "hello")
    }
    
    func sleepAndTalk(ctx context.Context, d time.Duration, msg string) {
    	select {
    	case <-ctx.Done():
    		fmt.Println(time.Now().Format("2006-01-02-15:04"), "context cancled")
    	case <-time.After(d):
    		fmt.Println(msg)
    	}
    }
    
    std: 2022-11-21-22:59 context cancled
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    withValue
    func Decorate(f http.HandlerFunc) http.HandlerFunc {
    	return func(w http.ResponseWriter, r *http.Request) {
    		ctx := r.Context()
    		// 随机 63 位整数作为 int64。
    		id := rand.Int63()
    		ctx = context.WithValue(ctx, reqIdkey, id)
    		r = r.WithContext(ctx)
    		f(w, r)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    整个代码参考以 http server、client、log
    server
    client
    http_log

  • 相关阅读:
    Scratch二次开发8:背景、角色、造型、声音后台管理
    BluePrism注册下载并安装-RPA第一章
    PASCAL VOC数据集格式文件夹下文件配置
    基于神经网络的语音识别
    ssm基于Springboot的大学生竞赛辅导网站系统java-maven项目
    二叉搜索树
    VSCode搭建ESP32 ESP-IDF开发环境-Windows
    YoloV5改进策略:复现HIC-YOLOv5,用于小物体检测
    单片机STM32有什么推荐的裸机编程架构
    痞子衡嵌入式:大话双核i.MXRT1170之单独在线调试从核工程的方法(IAR篇)
  • 原文地址:https://blog.csdn.net/noob_cherry/article/details/133687369