分享
  1. 首页
  2. 文章

聊聊golang的context

onepunchgo · · 2437 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang的context的主要用途在于在多个goroutine之间传递数据,管理多个goroutine的生命周期。实际的应用场景有比如,在http服务中,每个请求就对应一个goroutine,而请求之中可能又会调用别的api,而产生更多的goroutine,用context来管理这些goroutine就能比较方便在这些goroutine中传递数据和管理。

主要方法

func Background() Context 

Background() 返回一个空的context,这是一个根节点。

func TODO() Context

TODO()返回的也是一个空的context,它跟Background的区别在于目的,当你使用一个todo的context时,代码维护者便知道当时的设计意图是待定的。

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

WithCancel()派生一个带有取消方法的子context,这在递归操作context时十分有用。

func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)

WithDeadline()和WithTimeout()差不对,只不过两者传的参数不一样,一个传的是截止时间,一个是时间间隔。

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

WithValue()能够在context中带一些参数。

管理goroutine的原理

简单了解下context的方法之后,我们来探究一下为什么说context能管理goroutine。先看个小例子:

func doSomething(ch chan int, id int) {
 fmt.Println(id)
 t := rand.Intn(10)
 time.Sleep(time.Duration(t) * time.Second)
 fmt.Printf("I had slept %d seconds.\n", t)
 ch <- 1
}
func SomeGoRoutine() {
 ch := make(chan int)
 for i := 0; i < 3; i++ {
 go doSomething(ch, i)
 }
 <-ch
 fmt.Println("done")
}
/** output:
2
0
1
I had slept 1 seconds.
done
*/

有这样一个场景,我的http服务提供了一个api,在这个api中产生了n个goroutine,当其中一个goroutine发生了错误,我想要结束掉整个请求,返回一些错误信息给调用方。如果不用context,那么我们很容易想到用channel去实现这样的功能,在主函数中阻塞,在goroutine中将数据传进channel中,当channel接收到数据时,结束掉这个请求。context也是类似的原理,通过channel在goroutine之间的传递而实现goroutine的管理。比较有趣的是WithCancel这个方法,跟我们简单用channel去传递数据不同的是,WithCancel是派生一个子context,当子context要结束的时候,是递归地调用cancel方法,它的child也会调用cancel方法。示例如下:

func ContextCancel() {
 ctx := context.Background()
 go func(ctx context.Context) {
 ctx1, cancel := context.WithCancel(ctx)
 go func(ctx1 context.Context) {
 ctx2, _ := context.WithCancel(ctx1)
 select {
 case <-ctx2.Done():
 fmt.Println("ctx2")
 }
 }(ctx1)
 cancel()
 }(ctx)
 time.Sleep(10 * time.Second)
}
/** ouput:
ctx2
*/

欢迎关注我的公众号:onepunchgo,给我留言。

image

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:onepunchgo

查看原文:聊聊golang的context

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2437 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏