go context 读代码

...占位

1, 例子理解

// from https://blog.csdn.net/u011957758/article/details/82948750

package main

import (
	"context"
	"fmt"
	"math/rand"
	"time"
)
/*
1, main 和 chiHanBao 数据沟通
   main 通过 chan eatNum 从函数ChiHanBao 中读取数据
2, main 对 ChiHanBao的控制
   main 通过 cancel 影响 ctx ,影响 <-ctx.Done() ,实现对ChiHanBao的控制
*/

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	eatNum := chiHanBao(ctx)
	for n := range eatNum {
		if n >= 10 {
			cancel()
			break
		}
	}

	fmt.Println("正在统计结果。。。")
	time.Sleep(1 * time.Second)
}

func chiHanBao(ctx context.Context) <-chan int {
	c := make(chan int)
	// 个数
	n := 0
	// 时间
	t := 0
	go func() {
		for {
			//time.Sleep(time.Second)
			select {
			case <-ctx.Done():
				fmt.Printf("耗时 %d 秒,吃了 %d 个汉堡 
", t, n)
				return
			case c <- n:
				incr := rand.Intn(5)
				n += incr
				if n >= 10 {
					n = 10
				}
				t++
				fmt.Printf("我吃了 %d 个汉堡
", n)
			}
		}
	}()

	return c
}

2,...和第一个例子差不多

func main() {
    // ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10))
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	chiHanBao(ctx)
	defer cancel()
}

func chiHanBao(ctx context.Context) {
	n := 0
	for {
		select {
		case <-ctx.Done():
			fmt.Println("stop 
")
			return
		default:
			incr := rand.Intn(5)
			n += incr
			fmt.Printf("我吃了 %d 个汉堡
", n)
		}
		time.Sleep(time.Second)
	}
}

3,...生效时刻

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	go func() {
		// 服务连接
		if config.SslConfig.Enable {
			if err := srv.ListenAndServeTLS(config.SslConfig.Pem, config.SslConfig.KeyStr); err != nil && err != http.ErrServerClosed {
				log.Fatal("listen: ", err)
			}
		} else {
			if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
				log.Fatal("listen: ", err)
			}
		}
	}()
	// 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
	quit := make(chan os.Signal)
	signal.Notify(quit, os.Interrupt)
	<-quit
	fmt.Printf("%s Shutdown Server ... 
", pkg.GetCurrentTimeStr())
//  <-quit 会阻塞, 经过N久后,等用户输入了 Ctrl+C,=>srv.Shutdown(ctx),    context.WithTimeout中的超时5秒才生效
	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	log.Println("Server exiting")

4... withvalue

package main

import (
	"context"
	"log"
)

type Huzh string
type H1 struct {}

func main() {
	//ctx, cancle := context.WithTimeout(context.Background(), 5*time.Second)
	val1 := context.WithValue(context.Background(),Huzh("xx"),"hello")
	val2 := context.WithValue(context.Background(),H1{},"hello")
	ctxhand(val1,val2)
	log.Println("main exit")

}

func ctxhand(ctx1,ctx2 context.Context) {
	log.Println(ctx1.Value(Huzh("xx")))
	log.Println(ctx2.Value(H1{}))
}


===============
C:UsershuzhAppDataLocalTemp\___go_build_m_go.exe #gosetup
2021/07/07 22:18:34 hello
2021/07/07 22:18:34 hello
2021/07/07 22:18:34 main exit

  

原文地址:https://www.cnblogs.com/eiguleo/p/14781083.html