我们先看一段代码
func listen() { ticker := time.NewTicker(time.Second) for { select { case <-ticker.C: fmt.Println(time.Now()) } } } func main() { go listen() time.Sleep(time.Second * 5) fmt.Println("main exit") }
非常简单的一个goroutine用法,想必每个gopher都看过的。
不过在实际生产中,我们几乎看不到这种用法的的身影,原因很简单,我们无法实现对goroutine的控制,而一般业务中我们需要根据不同情况对goroutine进行各种操作。
要实现对goroutine的控制,一般有以下两种。
一、手动发送goroutine控制信号
这里我们发送一个退出goroutine的信号。
// listen 利用只读chan控制goroutine的退出 func listen(ch <-chan bool) { ticker := time.NewTicker(time.Second) for { select { case <-ticker.C: fmt.Println(time.Now()) case <-ch: fmt.Println("goroutine exit") return } } } func main() { // 声明一个控制goroutine退出的chan ch := make(chan bool, 1) go listen(ch) // 只写chan func(ch chan<- bool) { time.Sleep(time.Second * 3) fmt.Println("发送退出chan信号") ch <- true close(ch) }(ch) time.Sleep(time.Second * 5) fmt.Println("main exit") }
我们在main函数里发送一个控制goroutine的退出信息,在goroutine里我们会select这个通道,如果收到此信息,则直接退出goroutine。这里我们使用到了单向chan。
Continue reading