• 并发上下文控制包Context


    Context,是golang用来控制并发流程的库,它能方便的将主控程序的停止信号传递到goroutinue中,从而实现一键中止关联goroutinue的执行,除此之外,它还能将外部变量通过Value的接口传递到goroutinue中。Context是一个接口类型,可以看下面的代码的定义,可以提供一类代表上下文的值,此类型值是并发安全的,也就是说它可以被传播给多个goroutinue。

    // A Context carries a deadline, cancelation signal, and request-scoped values
    // across API boundaries. Its methods are safe for simultaneous use by multiple
    // goroutines.
    type Context interface {
        // Done returns a channel that is closed when this Context is canceled
        // or times out.
        Done() <-chan struct{}
    
        // Err indicates why this context was canceled, after the Done channel
        // is closed.
        Err() error
    
        // Deadline returns the time when this Context will be canceled, if any.
        Deadline() (deadline time.Time, ok bool)
    
        // Value returns the value associated with key or nil if none.
        Value(key interface{}) interface{}
    }
    
    

    如何获得contexts?

    context包提供从现有上下文值派生新上下文值的函数。这些值形成一棵树:当上下文被取消时,从它派生的所有上下文也被取消。
    这棵树的树根或者说根节点是一个在contex包中预定义好的Context值,它是全局唯一的。通过调用context.Background函数,我们就可以获取到它。
    根节点仅仅是一个最基本的支点,不能被撤销,也不携带任何数据

    // Background returns an empty Context. It is never canceled, has no deadline,
    // and has no values. Background is typically used in main, init, and tests,
    // and as the top-level Context for incoming requests.
    func Background() Context
    

    可以通过context.Background()获得一个初始Context。生成的context传递给WithCancel,WithDeadline,With Timeout,WithValue来生成不同的context。

    func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
    func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
    func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
    func WithValue(parent Context, key, val interface{}) Context
    

    这四个能衍生context的函数,都接受一个初始Context作为第一个参数。

    自己写的例子

    package main
    import (
      "fmt"
      "context"
      "time"
    )
    
    func subPeriodPrint(ctx context.Context, msg string) {
      for {
        stop := false
        select {
          case <-ctx.Done():
            fmt.Printf("Over
    ")
            stop = true
          default:
            fmt.Printf("print msg:%s
    ", msg)
            time.Sleep(time.Second * 1)
        }
        if stop {
          break
        }
      }
    }
    
    func main() {
      // cancel 用来主动发送撤销通知,因为是WithTimeout函数,定时时间到了也会撤销
      ctx, cancel := context.WithTimeout(context.Background(), time.Second * 1)
      for i:=0;i <=1;i++ {
        msg := fmt.Sprintf("current count is %d", i)
        go subPeriodPrint(ctx, msg)
      }
      // 可以设置为5秒和2秒查看打印的不同 
      time.Sleep(time.Second * 5)
      fmt.Println("manual cancel")
      cancel()
    }
    

    Ctx.WithValue

    WithValue可以将参数塞进context里去,可以实现中间件的功能。比如将将用户session和登陆信息在各个requests之间携带。
    设置value

    ctx := context.WithValue(parentContext, key, value)
    

    获取value

    value:=ctx.Value(key)
    

    Go语言实战笔记(二十)| Go Context
    Go Concurrency Patterns: Context
    Go Concurrency Patterns: Pipelines and cancellation

    ---恢复内容结束---

  • 相关阅读:
    Classview配置与访问
    MongoDB(NoSQL) 非关系型数据库
    服务器出现500错误的时候,让PHP显示错误信息
    Linux_目录介绍
    各类ip地址范围和私有地址范围
    Raid_磁盘冗余阵列
    Python_文件操作_读
    Git操作命令
    记录关于校园网登录不了腾讯的软件得问题解决
    关于科研方面分享的一些经验
  • 原文地址:https://www.cnblogs.com/linyihai/p/10294777.html
Copyright © 2020-2023  润新知