go context

type Context interface {

    Deadline() (deadline time.Time, ok bool)

    Done() <-chan struct{}

    Err() error

    Value(key interface{}) interface{}
}

Context接口包含四个方法:

  1. Deadline返回绑定当前context的任务被取消的截止时间;如果没有设定期限,将返回ok == false。
  2. Done 当绑定当前context的任务被取消时,将返回一个关闭的channel;如果当前context不会被取消,将返回nil。
  3. Err 如果Done返回的channel没有关闭,将返回nil;如果Done返回的channel已经关闭,将返回非空的值表示任务结束的原因。如果是context被取消,Err将返回Canceled;如果是context超时,Err将返回DeadlineExceeded。
  4. Value 返回context存储的键值对中当前key对应的值,如果没有对应的key,则返回nil。

父节点Context可以主动通过调用cancel方法取消子节点Context,而子节点Context只能被动等待。同时父节点Context自身一旦被取消(如其上级节点Cancel),其下的所有子节点Context均会自动被取消。

有三种创建方法:

// 带cancel返回值的Context,一旦cancel被调用,即取消该创建的context
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) 

// 带有效期cancel返回值的Context,即必须到达指定时间点调用的cancel方法才会被执行
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) 

// 带超时时间cancel返回值的Context,类似Deadline,前者是时间点,后者为时间间隔
// 相当于WithDeadline(parent, time.Now().Add(timeout)).
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"
)

var logg *log.Logger

func someHandler() {
    //ctx, cancel := context.WithCancel(context.Background())
    ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
    go doStuff(ctx)  //这个协程有5s的超时时间限制

    //10秒后取消doStuff
    time.Sleep(30 * time.Second)
    logg.Printf("wait")
    cancel()  // cancel被调用,即取消该创建的ctx

}

//每1秒work一下,同时会判断ctx是否被取消了,如果是就退出
func doStuff(ctx context.Context) {
    for {
        time.Sleep(1 * time.Second)
        select {
        case <-ctx.Done():
            logg.Printf("done")
            return
        default:
            logg.Printf("work")
        }
    }
}

func main() {
    logg = log.New(os.Stdout, "", log.Ltime)
    someHandler()
    logg.Printf("down")
}

以上执行结果:可以看出doStuff在5s之后执行结束(超时时间限制),context的cancel是在30s之后

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 目录 Context 基本使用方法 Context 使用场景 valueCtx使用示例结构体WithValue c...
    迈莫coding阅读 552评论 0 1
  • 控制并发有两种经典的方式:WaitGroup和Context WaitGroup:控制多个Goroutine同时完...
    JunChow520阅读 703评论 0 2
  • 1 什么是Context 最近在公司分析gRPC源码,proto文件生成的代码,接口函数第一个参数统一是ctx c...
    淘小铺刀仔阅读 349评论 0 1
  • Go context 在RPC或者Web服务中,当Server端接受一个request的时候,都会开启一个额外的g...
    qingshuiting阅读 8,755评论 0 2
  • context包以及包内方法用以维护一组goroutine间的生命周期的截止,以及同生命周期内的共享变量本文面向有...
    openex阅读 833评论 0 1