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

    已经全部退出了

    
    
  • 相关阅读:
    http请求的跨域
    事件驱动模型
    单例设计
    引用类型与垃圾回收
    注解开发
    Java的反射机制
    Android Listener 监听的几种写法
    人生必须有所规划,工作是好比马拉松
    Android 常用的常量
    Android 常见的广播 action常量
  • 原文地址:https://www.cnblogs.com/ksir16/p/8865002.html
Copyright © 2011-2022 走看看