0
点赞
收藏
分享

微信扫一扫

MIT6.5840 Lab 1: MapReduce(6.824)

千白莫 2024-11-19 阅读 19

context简介

因为context具有在多个不同goroutine中传递上下文信息的性质,所以其常用于并发控制。

下面是对context包的详细使用:

context的使用

创建一个context

context包提供了两种创建方式:

  • context.Background()
  • context.TODO()

这两种方式创建出来的是根context,不具有任何功能。需要根据实际选择context包提供的With系列函数来解决相应的问题。

下面是context包提供的With系列函数:

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
func WithValue(parent Context, key, val interface{}) Context

context的衍生具有树形结构的特点。

下面是对这些With函数的具体使用介绍:

With系列函数

WithCancel 取消控制

WithCancel的作用是,我们可以通过传递这样的上下文,去控制多个goroutine,通过cancel函数,在任意时刻让这些goroutine取消。

下面是例子:

func main() {  
    ctx, cancel := context.WithCancel(context.Background())  
    go task(ctx)  
    time.Sleep(5 * time.Second)  
    cancel()  
    time.Sleep(time.Second)  
}  
  
func task(ctx context.Context) {  
    for range time.Tick(time.Second) {  
       select {  
       case <-ctx.Done():  
          fmt.Println(ctx.Err())  
          return  
       default:  
          fmt.Println("tasking...")  
       }    
    }
}

超时控制

一个健壮的程序都是需要设置超时时间的,避免由于服务端长时间响应而消耗资源。所以,一些web框架都会采用WithDeadlineWithTimeOut函数来做超时控制。

下面是例子:

func main() {  
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)  
    defer cancel()  
    go task(ctx)  
    time.Sleep(6 * time.Second)  
}  
  
func task(ctx context.Context) {  
    for range time.Tick(time.Second) {  
       select {  
       case <-ctx.Done():  
          fmt.Println(ctx.Err())  
          return  
       default:  
          fmt.Println("tasking...")  
       }    
    }
}

WithValue 携带数据

WithValue函数可以返回一个可携带数据的context,可以用于在多个goroutine进行传递。
例如,在日常业务开发中,需要有一个trace_id来串联所有日志,那么就可以使用WithValue来实现。

下面是例子:

func main() {  
    ctx := context.WithValue(context.Background(), "key", "value")  
    go task(ctx)  
    time.Sleep(time.Second)  
}  
  
func task(ctx context.Context) {  
    fmt.Println(ctx.Value("key"))  
}

使用WithVlue的注意事项:

总结

context包在做并发控制上具有相当方便的功能,如在做任务的取消、超时以及传递隐式参数的情境。

举报

相关推荐

0 条评论