美文网首页Go语言学习笔记
go 基础学习(一)context是个什么鬼

go 基础学习(一)context是个什么鬼

作者: 六分钟热度 | 来源:发表于2020-11-30 22:28 被阅读0次

所谓的context,直译过来是上下文的意思。
在之前的学习中,碰到上下文的概念是在JVM运行时数据区的程序计数器中,代表线程切换时保存的数据,用以在线程切换回来时继续从之前的位置执行。

go中的context,要从三个方面说起:

  • 什么是context
  • context的应用场景
  • context源码解读
1.什么是context?

context是用来控制goroutine的一种方式:在复杂goroutine应用场景中,往往需要在api边界和过程之间传递截止时间、取消信号或者其他相关的数据

goroutine是轻量级线程,用于实现go的并发编程

2.context的应用场景

goroutine的使用方式一般有三种

  • WaitGroup
  • Channel
  • Context

WaitGroup的使用方式:先往waitgroup中添加job数量,之后在不同的goroutine执行wg.Done(),在主groutine中执行wg.Wait() 等待

func CtxWaitGroup() {
    var wg sync.WaitGroup
    wg.Add(2) //在waitgroup中添加job数量
    go func() {
        time.Sleep(2 * time.Second)
        fmt.Println("老财做账")
        wg.Done() // 通知waitgroup本job完成
    }()

    go func() {
        time.Sleep(1 * time.Second)
        fmt.Println("老财审单")
        wg.Done()
    }()
    wg.Wait() //等待waitgroup中的job完成
    fmt.Println("这就是老财们的日常工作")
}

Channel的使用方式:配合select使用,希望能主动停止某个goroutine,比如某个goroutine跑太久了,我们需要发送一个信息让他停止下来,这种情况下可以使用Channel+Select的模式

// 如何主动通知停止
func CtxStopInitiative() {
    stop := make(chan bool) // 定义一个channel,传递true/false
    go func() { // 创建一个goroutine
        for {
            select {
            case <-stop: // 如果channel接收到停止请求
                fmt.Println("You are fired!")
                return
            default: // 未接收到停止请求前
                fmt.Println("老财工作中")
                time.Sleep(1 * time.Second)
            }
        }
    }()

    time.Sleep(5 * time.Second) // 等待五秒
    fmt.Println("那个老财动作太慢了!开除!")
    stop <- true // 等不下去了,向channel发送一个停止请求
    time.Sleep(5 * time.Second)
}

Context的使用方式:上面两种情况应对的是单层的goroutine调度,如果是goroutine又创建了goroutine,类似一个项目分给几个组,几个组又分别安排给组里不同的成员完成。如果我们需要某个goroutine完成时,它的子goroutine也已经完成,可以通过Context实现。

func CtxContextManyGoroutine() {
    // 父goroutine其实创建了三个子goroutine:worker;
    // 而每个worker又创建了自己的goroutine;
    // 仍然在父goroutine创建一个context对象
  // 并将其通过函数参数,分发给所有worker,当父goroutine需要停止时
  // 调用cancel()函数,所有子goroutine会接收到<-ctx.Done()结束消息,作出相应处理
    ctx, cancel := context.WithCancel(context.Background())
    go worker(ctx, "老财1")
    go worker(ctx, "老财2")
    go worker(ctx, "老财3")
    time.Sleep(1 * time.Second) // 主goroutine阻塞1秒,观察三个worker-goroutine运行情况
    fmt.Println("建立财务共享中心,老财全部优化!")
    cancel() // ctx发出了结束信号,代表主goroutine即将结束
    time.Sleep(1 * time.Second)
    fmt.Println("老财们都滚蛋了!")
}
func worker(ctx context.Context, str string) {
    go func() {
        for {
            select {
            case <-ctx.Done(): // worker-goroutine接收到结束信号,打印消息后直接返回结束
                fmt.Println(str, " 你被优化了!")
                return
            default:
                fmt.Println(str, " 工作中")
                time.Sleep(1 * time.Second)
            }
        }
    }()
}

相关文章

  • go 基础学习(一)context是个什么鬼

    所谓的context,直译过来是上下文的意思。在之前的学习中,碰到上下文的概念是在JVM运行时数据区的程序计数器中...

  • Golang context初探

    什么是context 从go1.7开始,golang.org/x/net/context包正式作为context包...

  • 理解 Go context

    深入理解 Go Context 什么是 Context Context 的最常见但也是最不准确的翻译是 ‘上下文’...

  • GO 语言context.Context类型

    context.Context类型 context.Context类型(以下简称Context类型)是在Go 1....

  • Go Context 基础入门

    简介 context是Go中广泛使用的程序包,由Google官方开发在1.7版本引入。它用来简化在多个go rou...

  • GO实验(5)context包阅读

    环境 go1.18阿里云centos7 context结构体 context.Context是一个需要实现4个方法...

  • go 基础学习

    1 go 基础go 语法基础go 官方资料如果由C ,C++ 基础, 学习go 比较容易,本文学习go ,主要是为...

  • Go context 学习笔记

    golang 的 Context包,是专门用来简化对于处理单个请求的多个goroutine之间与请求域的数据、取消...

  • golang熟练运用context

    什么是context go从1.7版本之后开始引入了context,它的作用主要是传递上下文信息,像一个大容器,里...

  • Go Context上下文的应用

    Go的上下文应用 1.背景原理 Go上下文就是context。对于go来说go routine(协程)是一个非常有...

网友评论

    本文标题:go 基础学习(一)context是个什么鬼

    本文链接:https://www.haomeiwen.com/subject/bourwktx.html