go context学习

context学习

  • context的struct设计
type Context interface {
    Deadline() (deadline time.Time, ok bool)

    Done() <-chan struct{}

    Err() error

    Value(key interface{}) interface{}
}
  • struct中字段分析

    • Deadline()返回设置的截止时间和有无设置截止时间
    • Done()返回一个只读的chan,用来通知是否要释放资源
    • Err()返回取消的原因
    • Value(key interface{})获取绑定在context上的值,是一个键值对。这个值是线程安全的。(在并发情况下,能够正确处理这个共享变量)
  • context的常用方法实例

    • 参考代码
package main

import(
	"fmt"
	"time"
	"golang.org/x/net/context"
)

type faveContextKey string   //定义别名

func main(){
	fmt.Println("context包学习")
	UseContext()
	UseContextWithDeadline()
	UseContextWithTimeout()
	UseContextWithValue()
}


func UseContext(){
	// 使用withCancel生成上下文
	gen := func (ctx context.Context)<- chan int{
		dst := make(chan int)  //无缓冲,无长度
		n := 1
		fmt.Println("这个函数被调用多少次:",n)  //被调用一次
		go func (){
			for{
				select{
				// 多个case同时满足,就会随机执行case
				case <- ctx.Done():
					// 关闭上下文
					fmt.Println("ctx.Done",ctx.Err(),n)
					return
				case dst <- n:   //要么运行完这个作用域,要么就不用运行
					n++
					fmt.Printf("n = %v \n",n)
				}
			}
		}()
		//发送器
		return dst
	}
	ctx,cancel := context.WithCancel(context.Background())
	defer cancel()
	data := gen(ctx)
	for n:= range data{  //接收
		fmt.Println(n)
		if n== 16{
			break
		}
	}
}


func UseContextWithDeadline(){
	// withDeadline作用:设置context的存活期
	d := time.Now().Add(50 * time.Millisecond)
	ctx,cancel := context.WithDeadline(context.Background(),d)
	if ctx == nil{
		fmt.Println("ctx is nil")
		return
	}
	defer cancel()
	select{
	case <-time.After(time.Second*1):
		fmt.Println("overslept")
	case <- ctx.Done():
		fmt.Println(ctx.Err())
	}
}


func UseContextWithTimeout(){
	// withTimeout作用:设置context的存活期
	ctx,cancel := context.WithTimeout(context.Background(),50*time.Millisecond)
	if ctx == nil{
		fmt.Println("ctx is nil")
		return
	}
	defer cancel()
	select{
	case <-time.After(time.Second*1):
		fmt.Println("overslept")
	case <- ctx.Done():
		fmt.Println(ctx.Err())
	}
}

func UseContextWithValue(){
	// withValue作用:带值
	f := func(ctx context.Context,k faveContextKey){
		if v := ctx.Value(k);v!=nil{
			fmt.Printf("key:%v,value:%v \n",k,v)
		}else{
			fmt.Println("key not found!",k)
		}
	}
	k := faveContextKey("language")
	ctx:= context.WithValue(context.Background(),k,"go")
	if ctx==nil{
		fmt.Println("ctx is nil")
	}
	f(ctx,k)
	f(ctx,faveContextKey("color"))
}
  • context包的用途

    • 构建树形关系的上下文,实现上一层的Goruntine控制下一层的Goruntine。通过传递context的对象变量方式对下一层的Goruntine进行管控。通知信号为context对象中的Done()进行控制。
    • 参考用例

posted @ 2019-09-27 23:16  Myuniverse  阅读(255)  评论(0编辑  收藏  举报