Go Context 基础入门

简介

context是Go中广泛使用的程序包,由Google官方开发在1.7版本引入。它用来简化在多个go routine传递上下文数据、(手动/超时)中止routine树等操作,比如,官方http包使用context传递请求的上下文数据,gRpc使用context来终止某个请求产生的routine树。由于它使用简单,现在基本成了编写go基础库的通用规范。

1.使用入门:kv存储

  • context在整体上看就是一个树,每个节点只能存储一个kv对
  • Background() 创建一个根节点
  • WithValue() 父context衍生一个子context,并将key/value对保存到子节点。
  • Value() 从某个节点取出Value,子节点可以取到父节点的kv。

代码示例:

func main() {
    root := context.Background()
    ctx1 := context.WithValue(root, "key1", "value1")
    ctx2 := context.WithValue(ctx1, "key2", "value2")
    fmt.Println(ctx1.Value("key1"))
    fmt.Println(ctx1.Value("key11"))
    fmt.Println(ctx2.Value("key2"))
}

value1
<nil>
value2

2. 控制并发(goroutine)

当context节点close时,会触发 Done() 操作,goroutine可以接收次消息通知。

func main() {
    root := context.Background()
    //ctx1, cancel := context.WithDeadline(root, time.Now().Add(6 * time.Second))
    ctx1, cancel := context.WithCancel(root)
    ctx2 := context.WithValue(ctx1, "key2", "value2")
    go watch(ctx2)
    time.Sleep(10 * time.Second)
    fmt.Println("通知监控停止")
    cancel()
    time.Sleep(5 * time.Second)
}

func watch(ctx context.Context) {
    for {
        select {
        case <- ctx.Done():
            fmt.Println(ctx.Value("key2"), "监控退出了。")
            return
        default:
            fmt.Println(ctx.Value("key2"), "go rountine 监控中。。。")
            time.Sleep(2 * time.Second)
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。