ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Goroutine之context上下文

2022-02-04 11:01:41  阅读:161  来源: 互联网

标签:wg 协程 Goroutine sync Done context time 上下文


一、context上下文简介

context简单的理解就是上下文,它可以进行不同协程之间的通信,所以也就包含了上下文的环境等变量信息。有下面三种用法:

  • WithCancel 通过该方法可以达到一个协程在某一时刻控制另一个协程的退出
  • WithDeadline 通过该方法可以在一个协程在指定时间点控制另一个协程的退出
  • WithTimeout 通过该方法进行超时设置,一旦超时,相应的协程就会退出

二、使用方法

1、WithCancel 

 WithCancel返回一个带着Done通道的context副本以及一个cancel函数,这个带着Done通道的副本在cancel函数被调用或者父context的Done通道被关闭时,它就会关闭。

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func getInfo(ctx context.Context) {
    defer wg.Done()
    for {
        time.Sleep(time.Second)
        select {
        case <-ctx.Done(): // 检查cancel是否到时间执行
            fmt.Println("获取信息结束!")
            return
        default:
            fmt.Println("获取信息!")
        }
    }
}

func main() {
    wg.Add(1)
    ctx, cancel := context.WithCancel(context.Background())
    go getInfo(ctx)
    time.Sleep(time.Second * 5)
    cancel() // 5s后执行cancel函数
    wg.Wait()

}

/*
获取信息!
获取信息!
获取信息!
获取信息!
获取信息结束!
*/

2、WithDeadline 

WithDeadline返回一个带着截至日期的context副本,如果到达了截至日期,那么这个副本的Done通道的副本在cancel函数被调用或者父context的Done通道被关闭时,它就会关闭。

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func getInfo(ctx context.Context) {
    defer wg.Done()
    for {
        time.Sleep(time.Second)
        select {
        case <-ctx.Done(): // 到时间会自动调用cancel函数,结束协程函数
            fmt.Println("获取信息结束!")
            return
        default:
            fmt.Println("获取信息!")
        }
    }
}

func main() {
    wg.Add(1)
    d := time.Now().Add(time.Second * 5)
    ctx, _ := context.WithDeadline(context.Background(), d) // 如果没有返回cancel函数也是可行的,只要在规定的d时间内就自动结束传入ctx的函数
    go getInfo(ctx)
    wg.Wait()

}

/*
获取信息!
获取信息!
获取信息!
获取信息!
获取信息结束!
*/

3、WithTimeout

WithTimeout返回一个带着超时时间的context副本,如果到达了时间,那么这个Done通道的副本在cancel函数被调用或者父context的Done通道被关闭时,它就会关闭。

如果显式调用cancel函数,那么如果未在超时时间之前也可以结束相应的协程。

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func getInfo(ctx context.Context) {
    defer wg.Done()
    for {
        time.Sleep(time.Second)
        select {
        case <-ctx.Done(): // 到时间会自动调用cancel函数,结束协程函数
            fmt.Println("获取信息结束!")
            return
        default:
            fmt.Println("获取信息!")
        }
    }
}

func main() {
    wg.Add(1)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
    go getInfo(ctx)
    defer cancel() // 超时之后释放资源
    wg.Wait()

}

/*
获取信息!
获取信息!
获取信息!
获取信息!
获取信息结束!
*/

 

标签:wg,协程,Goroutine,sync,Done,context,time,上下文
来源: https://www.cnblogs.com/shenjianping/p/15859352.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有