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

已经全部退出了


posted @ 2018-04-17 13:46  yuchen16  阅读(1051)  评论(0编辑  收藏  举报