golang如何使用channel控制goroutine退出
最经典的处理方式:
在启动goroutine的时候,传递一个额外的chan型参数,用来接收退出信号,代码如下
func worker(name string, stopchan chan struct{}) { for { select { case <-stopchan: fmt.Println("receive a stop signal, ", name) return default: fmt.Println("I am worker ", name) time.Sleep(1 * time.Second) } } }
在main函数中应该如何发送stop信号呢?
func main() { stopCh := make(chan struct{}) go worker("a", stopCh) time.Sleep(1 * time.Second) stopCh <- struct{}{} time.Sleep(3 * time.Second) }
输出:
I am worker a I am worker a receive a stop signal, a Process finished with exit code 0
ok,从输出可以看出name为a的这个woker在收到信号之后退出了,过了2s后主函数退出
当我们又2个goroutine的时候情况如何呢?
func main() { stopCh := make(chan struct{}) go worker("a", stopCh) go worker("b", stopCh) time.Sleep(1 * time.Second) stopCh <- struct{}{} time.Sleep(3 * time.Second) }
输出:
I am worker a
I am worker b
I am worker b
I am worker a
receive a stop signal, a
I am worker b
I am worker b
I am worker b
也就是说a退出了,b没有退出,因为stopCh <- struct{}{}只发送一个信号,被a接收了,b不受影响
如果想让2个goroutine同时退出,需要这样写:
close(stopCh)
再看下输出:
I am worker a I am worker b I am worker a receive a stop signal, b receive a stop signal, a Process finished with exit code 0
已经全部退出了