zoukankan      html  css  js  c++  java
  • 如何优雅的关闭Golang Channel?

    Channel关闭原则

    不要在消费端关闭channel,不要在有多个并行的生产者时对channel执行关闭操作。
    也就是说应该只在[唯一的或者最后唯一剩下]的生产者协程中关闭channel,来通知消费者已经没有值可以继续读了。只要坚持这个原则,就可以确保向一个已经关闭的channel发送数据的情况不可能发生。

    暴力关闭channel的正确方法

    如果想要在消费端关闭channel,或者在多个生产者端关闭channel,可以使用recover机制来上个保险,避免程序因为panic而崩溃。

    func SafeClose(ch chan T) (justClosed bool) {
         defer func() {
            if recover() != nil {
                justClosed = false
            }
        }()
        close(ch)
        return true
    }
    

    使用这种方法明显违背了上面的channel关闭原则,然后性能还可以,毕竟在每个协程只会调用一次SafeClose,性能损失很小。
    同样也可以在生产消息的时候使用recover方法。

    礼貌关闭channel方法

    还有不少人经常使用sync.Once来关闭channel,这样可以确保只会关闭一次

    同样我们也可以使用sync.Mutex达到同样的目的。

    要知道golang的设计者不提供SafeClose或者SafeSend方法是有原因的,
    他们本来就不推荐在消费端或者在并发的多个生产端关闭channel,
    比如关闭只读channel在语法上就彻底被禁止使用了。

    优雅的关闭channel的方法

    多个消费者,单个生产者.

    多个生产者,单个消费者。


    就上面这个例子,生产者同时也是退出信号channel的接受者,退出信号channel仍然是由它的生产者

    多个生产者,多个消费者

  • 相关阅读:
    mycat
    人大金仓备份和还原
    文件断点上传,html5实现前端,java实现服务器
    MoChat
    PHP性能追踪及分析工具xhprof的安装与使用
    使用 satis 搭建一个私有的 Composer 包仓库
    sed命令用法详解
    rsync同步工具学习笔记
    服务器支持AspJpeg和JMail45_free.msi组件
    批处理——服务器的web文件备份
  • 原文地址:https://www.cnblogs.com/Csir/p/9848439.html
Copyright © 2011-2022 走看看