IT袋

当前位置:主页 > 经验教程 > 建站编程 >

Go context.WithCancel 的使用

Go context.WithCancel 的使用(2)

时间:2023-09-17 16:28:35 来源:IT袋 作者:苏晓敏
导读:Go context.WithCancel 的使用,在cancelCtx这个结构体中,字段done是一个传递空结构体类型的channel,用来在上下文取消时关闭这个通道,err就是在上下文被取消时告诉用户这个上下文取消

Go context.WithCancel 的使用

在cancelCtx这个结构体中,字段done是一个传递空结构体类型的channel,用来在上下文取消时关闭这个通道,err就是在上下文被取消时告诉用户这个上下文取消了,可以用ctx.Err()来获取信息

canceler是一个实现接口,用于Ctx的终止。实现该接口的Context有cancelCtx和timerCtx,而emptyCtx和valueCtx没有实现该接口。

Go context.WithCancel 的使用

// A canceler is a context type that can be canceled directly. The
// implementations are *cancelCtx and *timerCtx.
type canceler interface {
 cancel(removeFromParent bool, err error)
 Done() <-chan struct{}
}
// closedchan is a reusable closed channel.
var closedchan = make(chan struct{})
func init() {
 close(closedchan)
}
// cancel closes c.done, cancels each of c's children, and, if
// removeFromParent is true, removes c from its parent's children.
/**
* 1、cancel(...)当前Ctx的子节点
* 2、从父节点中移除该Ctx
**/
func (c *cancelCtx) cancel(removeFromParent bool, err error) {
 if err == nil {
  panic("context: internal error: missing cancel error")
 }
 c.mu.Lock()
 if c.err != nil {
  c.mu.Unlock()
  return // already canceled
 }
 // 设置取消原因
 c.err = err
 //  设置一个关闭的channel或者将done channel关闭,用以发送关闭信号
 if c.done == nil {
  c.done = closedchan
 } else {
  close(c.done) // 注意这一步
 }
  // 将子节点context依次取消
 for child := range c.children {
  // NOTE: acquiring the child's lock while holding parent's lock.
  child.cancel(false, err)
 }
 c.children = nil
 c.mu.Unlock()
 if removeFromParent {
   // 将当前context节点从父节点上移除
  removeChild(c.Context, c)
 }
}

对于cancel函数,其取消了基于该上下文的所有子上下文以及把自身从父上下文中取消

对于更多removeFromParent代码分析,和其他Context的使用,强烈建议阅读 深入理解Golang之Context(可用于实现超时机制)[4]

// Done is provided for use in select statements:
 //
 //  // Stream generates values with DoSomething and sends them to out
 //  // until DoSomething returns an error or ctx.Done is closed.
 //  func Stream(ctx context.Context, out chan<- Value) error {
 //   for {
 //    v, err := DoSomething(ctx)
 //    if err != nil {
 //     return err
 //    }
 //    select {
 //    case <-ctx.Done():
 //     return ctx.Err()
 //    case out <- v:
 //    }
 //   }
 //  }
 //
 // See https://blog.golang.org/pipelines for more examples of how to use
 // a Done channel for cancellation.
 Done() <-chan struct{}
 // If Done is not yet closed, Err returns nil.
 // If Done is closed, Err returns a non-nil error explaining why:
 // Canceled if the context was canceled
 // or DeadlineExceeded if the context's deadline passed.
 // After Err returns a non-nil error, successive calls to Err return the same error.
 Err() error

相关阅读

  • 开网站需要多少钱 公司网页制作流程及费用

    开网站需要多少钱 公司网页制作流程及费用

    一篇很详细的教程是关于开网站需要多少钱和公司网页制作流程及费用的相关经验,接下来IT袋带大家一起了解。 这个问题可以说是网站建设常见问题最热门的问题,也是客户咨询的最多的问

  • 简单的网站设计模板 一个完整的网页设计流程

    简单的网站设计模板 一个完整的网页设计流程

    本文导读:简单的网站设计模板和一个完整的网页设计流程的电脑小知识,一起来看看吧! 随着个人创业的流行,很多个人也需要一个比较详细的网站来展示自己,开展个人业务,或者积累粉

  • 哔哩哔哩是网站吗 哔哩哔哩是个什么网站

    哔哩哔哩是网站吗 哔哩哔哩是个什么网站

    小编为你解答哔哩哔哩是个什么网站的IT小经验,哔哩哔哩是中国年轻世代高度聚集的文化社区和视频网站,简称B站,B站早期是一个ACG(动画、漫画、游戏)内容创作与分享的视频网站。

  • python工具有哪些 新手python编程入门自学知识

    python工具有哪些 新手python编程入门自学知识

    为大家分享python工具有哪些和新手python编程入门自学知识的介绍,如有不对的地方欢迎指正! 随着python的火热,不少的程序员业余时间都会研究这门编程语言。 利用python开发,大牛用vim,接了