Go并发编程-context底层实现

cancelCtx实现

cancelCtx 也是典型的装饰器模式:在已有Context 的基础上,加上取消的功能。
核心实现:

  • Done方法是通过类似于 double-check 的机制写的。这种原子操作和锁结合的用法比较罕见。(思考:能不能换成读写锁?

  • 利用 children来维护了所有的衍生节点,难点就在于它是如何维护这个衍生节点。

    double-check-1:
    done是一个原子变量,有load()方法。如果channel不为nil,即放返回。
    double-check-2:
    为nil则使用锁,加载channel并store到原子变量。

在这里插入图片描述

children: 核心是儿子把自己加进去父亲的children字段里面。

但是因为Context里面存在非常多的层级,所以父亲不一定是 cancelCtx,因此本质上是找最近属于 cancelCtx 类型的祖先,然后儿子把自己加进去。

cancel就是遍历children,挨个调用cancel。然后儿子调用孙子的cancel,子子孙孙无穷匮也。

在这里插入图片描述
parentCancelCtx 寻找第一个待cancel的父辈context,并加入children。

cancel

核心的cancel方法,做了两件事:

  • 遍历所有的children
  • 关闭done这个channel:这个符合谁创建谁关闭的原则‘
    (利用了被关闭的channel永远能读到零值的特性,完成信号的发放)
    在这里插入图片描述

timerCtx实现

timerCtx也是装饰器模式:在已有cancelCtx的基础上增加了超时的功能。
实现要点:

  • WithTimeout 和 WithDeadline 本质一样WithDeadline 里面,
  • 在创建 timerCtx 的时候利用 time.AfterFunc 来实现超时

在这里插入图片描述

context包使用注意

  • 一般只用做方法参数,而且是作为第一个参数;
  • 所有公共方法,除非是 util, helper 之类的方法(纯粹工具类,计算不会花费很长时间的 ) ,否则都加上 context 参数。
  • 注意当与第三方,如调用方、数据库、Redis等打交道,一定要加context参数,以便于超时控制、链路控制等。
  • 不要用作结构体字段,除非你的结构体本身也是表达一个上下文的概念。
    (如HttpRequest 可以加到结构体字段)

context 提问要点

context.Context 使用场景:上下文传递(KV)控制
context.Context 原理:

  • 父亲如何控制儿子:通过儿子主动加入到父亲的children里面,父亲只需要遍历就可以。
  • valueCtx和timeCtx的原理(timeCtx在cancelCtx基础上加time.AfterFunc)

context四个核心方法API使用场景,在什么时候使用,有什么样的特性。关注一下。

context四个接口核心方法,如Err的返回值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值