• 我为什么错怪了goroutine


    前段时间写了篇随笔:
    我错怪了goroutine
    有点长,本文缩一下。

    我并不懂golang,只会照猫画虎,我一直以为goroutine是比thread更轻量的执行体,系统开销依然会随着goroutine的数量而线性增加,在大并发场景显然存在扩展性问题,但其实并不是。

    下图解释:
    在这里插入图片描述
    左上角是传统方式,有扩展性问题,右上角是异步方式,epoll收事件,loop处理,这是大家都认可的方式,下面是goroutine方式,和异步方式差异是不用自己loop事件,runtime帮调度,没有系统开销,为啥就觉得它会跟传统方式一样呢?

    如果不用routine这个词,或者至少不翻译成“X程”,拿它和thread,process对比的动机就降低了,runtime对goroutine的调度也别叫“调度”,而称“分发”,我想会好很多。

    好了,以上就是关于我错怪了goroutine的原因总结。下面的内容是今天和一位朋友聊到的一些想法,不属于本文的主体。

    一位朋友提到协程池是开历史倒车,我表示认同。仅就goroutine池化而言,我想是对goroutine误解的产物,goroutine池化显然是对runtime的不信任,所以试图自己控制goroutine数量从而降低调度开销。如果真是想榨取被runtime的方便性而夺去的那一丢丢性能,干嘛不用C呢。使用golang,图的就是方便,那必然要用一些性能来换,幸运的是,并不贵,只需一点点性能损耗。

    并不存在线性递增的调度开销。

    因为我不懂golang,所以我一开始觉得one goroutine per conn会有扩展性问题,简单了解goroutine原理后,我发现这反而是优势。用写线程的思维去写goroutine,很容易写出协程池这种东西。也因为我不懂golang,我才能迅速领悟goroutine的真实。

    总之,如果用golang,就把一切交给runtime吧,它能hold住大多数场景,剩下的如果需要极致,那就用C。C刚流行的时候,肯定也有人以优化为由将它写成汇编的形式,大量用goto,拒绝函数调用。

    优化是万恶之源,历史只会不断重演。

    我越来越觉得goroutine好,它把手写event loop转换成了goroutine的调度,这才是真正的“编程者只关注业务逻辑”而不必再了解框架,只需要在函数前面写一个go即可。这太棒了,写一篇随感。

    浙江温州皮鞋湿,下雨进水不会胖。

  • 相关阅读:
    设计模式-14责任链模式(责任链设计模式)详解
    2022年Java后端面试题,备战秋招,查缺补漏,吃透16套专题技术栈
    通过YOLO5训练自己的数据集(以交通标志牌数据集TT100k为例)
    [华为杯研究生创新赛 2023] 初赛 REV WP
    【经验分享】openGauss容灾集群搭建
    系统架构师2022年案例分析考前
    【Android笔记20】Android中的字符串、颜色、尺寸等资源的介绍及使用
    初级程序员如何进阶
    linux下二进制安装docker最新版docker-24.0.6
    盘点Win前端开发下常用的软件
  • 原文地址:https://blog.csdn.net/dog250/article/details/124739127