Go 第15章 上下文context Go 第15章 上下文context

2023-09-26

一、WithCancel

创建一个带有 Clear() 关闭函数的 ctx

没有使用 context

package main

import (
   "fmt"
   "time"
)

func main() {
   flag := make(chan bool)
   message := make(chan int)
   go son(flag, message)
   for i := 1; i <= 10; i++ {
      message <- i
   }
   flag <- true
   time.Sleep(time.Second)
   fmt.Println("主进程结束")
}

func son(flag chan bool, msg chan int) {
   t := time.Tick(time.Second)
   for _ = range t {
      select {
      case m := <-msg:
         fmt.Printf("接收到值 %d\n", m)
      case <-flag:
         fmt.Println("我结束了")
         return
      }
   }
}

使用 context

package main

import (
   "context"
   "fmt"
   "time"
)

func main() {
   ctx, clears := context.WithCancel(context.Background())
   message := make(chan int)
   go son(ctx, message)
   for i := 1; i <= 10; i++ {
      message <- i
   }
   clears()
   time.Sleep(time.Second)
   fmt.Println("主进程结束")
}

func son(ctx context.Context, msg chan int) {
   t := time.Tick(time.Second)
   for _ = range t {
      select {
      case m := <-msg:
         fmt.Printf("接收到值 %d\n", m)
      case <-ctx.Done():
         fmt.Println("我结束了")
         return
      }
   }
}

二、WithDeadline

创建一个带有超时时间点的 ctx

package main

import (
   "context"
   "fmt"
   "time"
)

func main() {
   ctx, clears := context.WithDeadline(context.Background(), time.Now().Add(time.Second*8))
   message := make(chan int)
   go son(ctx, message)
   for i := 1; i <= 10; i++ {
      message <- i
   }
   clears()
   time.Sleep(time.Second)
   fmt.Println("主进程结束")
}

func son(ctx context.Context, msg chan int) {
   t := time.Tick(time.Second)
   for _ = range t {
      select {
      case m := <-msg:
         fmt.Printf("接收到值 %d\n", m)
      case <-ctx.Done():
         fmt.Println("我结束了")
         return
      }
   }
}

三、WithTimeout

创建一个有超时时间的 ctx

package main

import (
   "context"
   "fmt"
   "time"
)

func main() {
   ctx, clears := context.WithTimeout(context.Background(), time.Second*8)
   message := make(chan int)
   go son(ctx, message)
   for i := 1; i <= 10; i++ {
      message <- i
   }
   clears()
   time.Sleep(time.Second)
   fmt.Println("主进程结束")
}

func son(ctx context.Context, msg chan int) {
   t := time.Tick(time.Second)
   for _ = range t {
      select {
      case m := <-msg:
         fmt.Printf("接收到值 %d\n", m)
      case <-ctx.Done():
         fmt.Println("我结束了")
         return
      }
   }
}

四、WithValue

创建一个携带了参数的 ctx

package main

import (
   "context"
   "fmt"
   "time"
)

func main() {
   ctx1 := context.WithValue(context.Background(), "name", "鲁鲁槟")
   ctx, clears := context.WithCancel(ctx1)
   message := make(chan int)
   go son(ctx, message)
   for i := 1; i <= 10; i++ {
      message <- i
   }
   clears()
   time.Sleep(time.Second)
   fmt.Println("主进程结束")
}

func son(ctx context.Context, msg chan int) {
   t := time.Tick(time.Second)
   for _ = range t {
      select {
      case m := <-msg:
         fmt.Printf("接收到值 %d\n", m)
      case <-ctx.Done():
         fmt.Println("我结束了", ctx.Value("name"))
         return
      }
   }
}

五、Context 基础接口

  • Deadline()

  • Done()

  • Err()

  • Value()

六、TODO

不确定是否需要使用的时候使用

七、Background

确定使用的时候使用

阅读 449