停止goroutine有几种方法

第一种方法,关闭channel。就是借助 channel 的 close 机制来完成对 goroutine 的精确控制。

func main() {
 ch := make(chan string, 6)
 go func() {
  for {
   v, ok := <-ch
   if !ok {
    fmt.Println("结束")
    return
   }
   fmt.Println(v)
  }
 }()

 ch <- "煎鱼还没进锅里..."
 ch <- "煎鱼进脑子里了!"
 close(ch)
 time.Sleep(time.Second)
}

第二种方法,定期轮询 channel。是更为精细的方法,其结合了第一种方法和类似信号量的处理方式。

func main() {
 ch := make(chan string, 6)
 done := make(chan struct{})
 go func() {
  for {
   select {
   case ch <- "脑子进煎鱼了":
   case <-done:
    close(ch)
    return
   }
   time.Sleep(100 * time.Millisecond)
  }
 }()

 go func() {
  time.Sleep(3 * time.Second)
  done <- struct{}{}
 }()

 for i := range ch {
  fmt.Println("接收到的值: ", i)
 }

 fmt.Println("结束")
}

第三种方法,可以借助 Go 语言的上下文(context)来做 goroutine 的控制和关闭。

func main() {
 ch := make(chan struct{})
 ctx, cancel := context.WithCancel(context.Background())

 go func(ctx context.Context) {
  for {
   select {
   case <-ctx.Done():
    ch <- struct{}{}
    return
   default:
    fmt.Println("煎鱼还没到锅里...")
   }

   time.Sleep(500 * time.Millisecond)
  }
 }(ctx)

 go func() {
  time.Sleep(3 * time.Second)
  cancel()
 }()

 <-ch
 fmt.Println("结束")
}

 

posted @ 2022-10-17 14:51  Mr.peter  阅读(74)  评论(0编辑  收藏  举报