Context包详解

Context是官方标准库中很常用的包,主要用于提供生命周期以及中断信号的控制,也用于API以及协程间通信,使用的场景非常多,下面介绍其中几个常用的函数

Background()

该方法用于初始化一个空的上下文

WithValue

WithValue 用于向上下文中的传递值,在一些API框架中使用频率非常高

例如:

1
2
3
4
5
6
7
8
func TestWithValue(t *testing.T) {

init := context.Background()

newContext := context.WithValue(init, "name", "jack")

fmt.Println(newContext.Value("name"))
}

WithCancel

WithCancel 创建一个带关闭的通道的上下文,以下是函数的定义:

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

该函数返回一个新的上下文以及一个取消函数,如果调用这个取消函数,那么我们可以通过Done函数得到通知

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func TestWithCancel(t *testing.T) {

forever := make(chan int)

cancelContext, cancelFunc := context.WithCancel(context.Background())

go func() {
for {
select {
case <-cancelContext.Done():
fmt.Println("canceled")
forever <- 1
return
default:
fmt.Println("do other things")
time.Sleep(1 * time.Second)
}
}
}()

time.Sleep(3 * time.Second)
cancelFunc()

<-forever
}

WithDeadline

WithDeadline 创建一个有生命周期的上下文以下是他的函数定义:

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

返回值和WithCancel一样,注意这个CancelFunc如果在生命周期结束前调用,可以提前结束上下文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func TestWithDeadline(t *testing.T) {

forever := make(chan int)

deadLineContext, cancelFunc := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))

// 函数结束后,销毁,释放内存
defer cancelFunc()

go func() {
for {
select {
case <-deadLineContext.Done():
fmt.Println("deadlined")
forever <- 1
return
default:
fmt.Println("do other things")
time.Sleep(1 * time.Second)
}
}
}()

<-forever
}

WithTimeout

WithTimeout与WithDeadline类似,只是一个是设定了截止时间,而一个是设置从当前时间后存活多久,换算后,其实一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func TestWithTimeout(t *testing.T) {

forever := make(chan int)

timeoutContext, cancelFunc := context.WithTimeout(context.Background(), 5*time.Second)

defer cancelFunc()

go func() {
for {
select {
case <-timeoutContext.Done():
fmt.Println("timeout")
forever <- 1
return
default:
fmt.Println("do other things")
time.Sleep(1 * time.Second)
}
}
}()

<-forever
}


Context包详解
https://www.xinyublog.com/golang/context/
作者
蚂蚁
发布于
2023年8月16日
许可协议