zoukankan      html  css  js  c++  java
  • 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

    已经全部退出了

    
    
  • 相关阅读:
    Yii框架中ActiveRecord使用Relations
    MySQL外键约束On Delete、On Update各取值的含义
    30种mysql优化sql语句查询的方法
    PHP数组常用函数
    yii CListView中使用CArrayDataProvider自定义数组作为数据
    java日常统计
    软件工程概论———登录界面的设计
    Java课堂疑问解答与思考5
    Java课堂疑问解答与思考4
    字符串加密
  • 原文地址:https://www.cnblogs.com/ksir16/p/8865002.html
Copyright © 2011-2022 走看看