GoLang context包如何使用

本文小编为大家详细介绍“GoLang context包如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“GoLang context包如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

背景

在父子协程协作过程中, 父协程需要给子协程传递信息, 子协程依据父协程传递的信息来决定自己的操作.

这种需求下可以使用 context 包

简介

Context通常被称为上下文,在go中,上层的协程可以将context 传给下层的协程, 来实现协程之间的信息传递, 同时下层协程也可以将context 传给更下层的协程, 来形成一张树状图.

主要方法

获得顶级上下文

首先要获得最顶级协程使用的Context

func Background() Context

Background 方法一般创建根 Context 的时候。

func TODO() Context

TODO 方法,当不清楚使用哪个上下文时,可以使用 TODO 方法。

当前协程上下文的操作

针对 Context 可以执行如下操作.

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

Deadline 方法返回结果有两个,第一个是截止时间,到了这个截止时间,Context 会自动取消;第二个是一个 bool 类型的值,如果 Context 没有设置截止时间,第二个返回结果是 false,如果需要取消这个 Context,就需要调用取消函数。

Done() <-chan struct{}

Done 方法返回一个只读的 channel 对象,类型是 struct{},在 goroutine 中,如果 Done 方法返回的结果可以被读取,代表父 Context 调用了取消函数。

Err() error

Err 方法返回 Context 被取消的原因。

Value(key interface{}) interface{}

Value 方法返回此 Context 绑定的值。它是一个 kv 键值对,通过 key 获取对应 value 的值

创建下级协程的Context

我们要依据父级的协程的Context创建子级协程的Context

WithCancel(parent Context) (ctx Context, cancel CancelFunc)

WithCancel 方法,基于父 Context,接收一个父 Context 参数,生成一个新的子 Context,和一个 cancel 函数,用于取消 Context。

WithDeadline(parent Context, d time.Time) (Context, CancelFunc)

WithDeadline 方法,基于父 Context,接收一个父 Context 参数,和一个截止时间的参数,生成一个新的子 Context,和一个 cancel 函数,可以使用 cancel 函数取消 Context,也可以等到截止时间,自动取消 Context。

WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

WithTimeout 方法,基于父 Context,接收一个父 Context 参数,和一个超时时间的参数,生成一个新的子 Context,和一个 cancel 函数,可以使用 cancel 函数取消 Context,也可以等到超时时间,自动取消 Context。

WithValue(parent Context, key, val interface{}) Context

WithValue 方法,基于父 Context,生成一个新的子 Context,携带了一个 kv 键值对,一般用于传递上下文信息。

场景示例

公司下班, 要领导下班后, 员工才下班, 但是员工忍耐也是有限度的, 领导老是不下班, 员工就自己走了.

package main
import (
	"context"
	"fmt"
	"time"
)
var name string
func main() {
	// 顶级Conxt, 领导
	up_context := context.Background()
	// 创建领导的下级 员工的的Context, 员工就最多加班5秒, 超过5秒领导不下班. 员工就下班了
	ctx, cancle := context.WithTimeout(up_context, time.Second*5)
	go work(ctx, "小卡拉")
	// 父线程等待3秒, 领导加班3秒
	time.Sleep(time.Second * 3)
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "领导下班了!")
	// 领导下班调用cancle(), 取消员工的 Context
	cancle()
	time.Sleep(time.Second * 5)
}
func work(ctx context.Context, name string) {
	for {
		select {
		// 看看员工的 Context 还在不在
		case <-ctx.Done():
			fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "下班!")
			return
		default:
			fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "加班!。")
			time.Sleep(time.Second * 1)
		}
	}
}

上面的代码中up_context 是最顶级的 Context 是使用context.Background()创建出来的, 员工的 Context对象 ctx 则是使用最顶级的up_context 并且使用WithTimeout方法创建出来的, 表示如果5秒内不调用返回的 cancel 方法, 就会自动取消, 对应员工最多等待领导五秒. 上面的执行结果是:

GoLang context包如何使用

可以看到, 领导就加班了3秒, 领导一下班, 员工就下班了.

如果领导加班7秒呢, 代码改成如下

package main
import (
	"context"
	"fmt"
	"time"
)
var name string
func main() {
	// 顶级Conxt, 领导
	up_context := context.Background()
	// 创建领导的下级 员工的的Context, 员工就最多加班5秒, 超过5秒领导不下班. 员工就下班了
	ctx, cancle := context.WithTimeout(up_context, time.Second*5)
	go work(ctx, "小卡拉")
	// 父线程等待7秒, 领导加班7秒
	time.Sleep(time.Second * 7)
	fmt.Println(time.Now().Format("2006-01-02 15:04:05"), "领导下班了!")
	// 领导下班调用cancle(), 取消员工的 Context
	cancle()
	time.Sleep(time.Second * 5)
}
func work(ctx context.Context, name string) {
	for {
		select {
		// 看看员工的 Context 还在不在
		case <-ctx.Done():
			fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "下班!")
			return
		default:
			fmt.Println(time.Now().Format("2006-01-02 15:04:05"), name, "加班!。")
			time.Sleep(time.Second * 1)
		}
	}
}

执行结果如下

GoLang context包如何使用

可以看到, 领导加班7秒, 员工并没有等着领导下班, 在第五秒的时候自己下班了.

读到这里,这篇“GoLang context包如何使用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程之家行业资讯频道。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


类型转换 1、int转string 2、string转int 3、string转float 4、用户结构类型转换
package main import s &quot;strings&quot; import &quot;fmt&quot; var p = fmt.Println func main() { p(&quot;Contains: &quot;, s.Contains(&quot;test&quo
类使用:实现一个people中有一个sayhi的方法调用功能,代码如下: 接口使用:实现上面功能,代码如下:
html代码: beego代码:
1、读取文件信息: 2、读取文件夹下的所有文件: 3、写入文件信息 4、删除文件,成功返回true,失败返回false
配置环境:Windows7+推荐IDE:LiteIDEGO下载地址:http://www.golangtc.com/downloadBeego开发文档地址:http://beego.me/docs/intro/ 安装步骤: 一、GO环境安装 二、配置系统变量 三、Beego安装 一、GO环境安装 根
golang获取程序运行路径:
Golang的文档和社区资源:为什么它可以帮助开发人员快速上手?
Golang:AI 开发者的实用工具
Golang的标准库:为什么它可以大幅度提高开发效率?
Golang的部署和运维:如何将应用程序部署到生产环境中?
高性能AI开发:Golang的优势所在
本篇文章和大家了解一下go语言开发优雅得关闭协程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。1.简介本文将介绍首先为什么需要主...
这篇文章主要介绍了Go关闭goroutine协程的方法,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。1.简介本文将介绍首先为什么需要主动关闭gor...
本篇文章和大家了解一下go关闭GracefulShutdown服务的几种方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。目录Shutdown方法Regi...
这篇文章主要介绍了Go语言如何实现LRU算法的核心思想和实现过程,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。GO实现Redis的LRU例子常
今天小编给大家分享的是Go简单实现多租户数据库隔离的方法,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会...
这篇“Linux系统中怎么安装NSQ的Go语言客户端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希
本文小编为大家详细介绍“怎么在Go语言中实现锁机制”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么在Go语言中实现锁机制”文章能帮助大家解决疑惑,下面...
今天小编给大家分享一下Go语言中interface类型怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考