停止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("结束") }