zoukankan      html  css  js  c++  java
  • 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)
    				}
    			}
    		}()
    		//发送器
    		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 
    ",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()进行控制。
      • 参考用例

  • 相关阅读:
    .NET Core自定义TagHelper和使用Serilog
    .NET Core CSRF
    jq 获取表单全部数据
    Webuploader 简单图片上传 支持多图上传
    CF-1451 E Bitwise Queries 异或 交互题
    CF-1440C2 Binary Table (Hard Version) (构造,模拟)
    CF-1445 C
    ACM模板_axiomofchoice_extra
    Codeforces Round #678 (Div. 2) 题解 (A-E)
    Oracle数据同步
  • 原文地址:https://www.cnblogs.com/MyUniverse/p/11600981.html
Copyright © 2011-2022 走看看