通过channel实现goroutine退出
一些情况下,需要通知正在运行的goroutine结束运行,go语言并没有提供结束goroutine的标准方式,这会导致goroutine之间的共享变量处在未定义的状态上。这个时候可以借助管道实现goroutine的退出。
不同的goroutine之间主要通过channel实现通信和同步。实现goroutine的退出,需要使用select关键字实现,select关键字用于同时处理多个管道的读写操作。select类似于switch,有多个分支,但每个分支都是对管道的读或写操作(default除外)。在多分支的情况下,如果没有可以执行的分支就会执行default分支;如果有多个分支可用,会随机选择一个分支执行。
下面是具体的代码实现:
package main
import (
"fmt"
"sync"
"time"
)
//worker函数
func worker(wg *sync.WaitGroup, cancel chan int) {
defer wg.Done()
for {
select { //循环从管道中读取数据,如果读到数据结束当前goroutine运行
case <-cancel:
fmt.Println("over")
return
default:
fmt.Println("running")
}
}
}
func main() {
//定义一个管道,用于发送退出信号
cancel := make(chan int)
//定义sync.WaitGroup,用于让main线程等待所有goroutine的退出工作完成
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ { //循环启动goroutine
wg.Add(1)
go worker(&wg, cancel)
}
//sleep 10s后关闭退出channel,关闭后goroutine就能从channel中读取数据
time.Sleep(10 * time.Second)
close(cancel)
//等待所有gouroutine 退出工作完成,再结束main线程
wg.Wait()
}