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 }
|