美文网首页
2021-06-20

2021-06-20

作者: 陈光岚_强化班 | 来源:发表于2021-06-20 13:44 被阅读0次

go自从出生就身带“高并发”的标签,其并发编程就是由groutine实现的,因其消耗资源低,性能高效,开发成本低的特性而被广泛应用到各种场景,例如服务端开发中使用的HTTP服务,在golang net/http包中,每一个被监听到的tcp链接都是由一个groutine去完成处理其上下文的,由此使得其拥有极其优秀的并发量吞吐量

for {

        // 监听tcp

        rw, e := l.Accept()

        if e != nil {

            .......

        }

        tempDelay = 0

        c := srv.newConn(rw)

        c.setState(c.rwc, StateNew) // before Serve can return

        // 启动协程处理上下文

        go c.serve(ctx)

}

虽然创建一个groutine占用的内存极小(大约2KB左右,线程通常2M左右),但是在实际生产环境无限制的开启协程显然是不科学的,比如上图的逻辑,如果来几千万个请求就会开启几千万个groutine,当没有更多内存可用时,go的调度器就会阻塞groutine最终导致内存溢出乃至严重的崩溃,所以本文将通过实现一个简单的协程池,以及剖析几个开源的协程池源码来探讨一下对groutine的并发控制以及多路复用的设计和实现。

一个简单的协程池

主播管理系统中信息不完整的主播找出来然后再到其相对应的直播平台爬取完整信息并补全,当时考虑到每一个主播的数据都要访问一次直播平台所以就用应对每一个主播开启一个groutine去抓取数据,虽然这个业务量还远远远远达不到能造成groutine性能瓶颈的地步,但是心里总是不舒服,于是将其优化成从协程池中控制groutine数量再开启爬虫进行数据抓取。思路其实非常简单,用一个channel当做任务队列,初始化groutine池时确定好并发量,然后以设置好的并发量开启groutine同时读取channel中的任务并执行,

实现

type SimplePool struct {

    wg  sync.WaitGroup

    work chan func() //任务队列

}

func NewSimplePoll(workers int) *SimplePool {

    p := &SimplePool{

        wg:  sync.WaitGroup{},

        work: make(chan func()),

    }

    p.wg.Add(workers)

    //根据指定的并发量去读取管道并执行

    for i := 0; i < workers; i++ {

        go func() {

            defer func() {

                // 捕获异常 防止waitGroup阻塞

                if err := recover(); err != nil {

                    fmt.Println(err)

                    p.wg.Done()

                }

            }()

            // 从workChannel中取出任务执行

            for fn := range p.work {

                fn()

            }

            p.wg.Done()

        }()

    }

    return p

}

// 添加任务

func (p *SimplePool) Add(fn func()) {

    p.work <- fn

}

// 执行

func (p *SimplePool) Run() {

    close(p.work)

    p.wg.Wait()

}

相关文章

  • 小棉袄的父亲节礼物

    2021-06-20 晴热 周日 “猪爸,帮我去取快递!”前天,正在做作业的宝贝对我说。 “啥,你...

  • 2022-06-26 思考成长周复盘(第105/130周)

    一 时间 2021-06-20 ~ 2022-06-26 二 行动回顾与反思 1 生活作息(2022年度早起目标:...

  • 没有什么不可能

    日记843篇 2021-06-20 有些技能越早弄懂越好,例如智慧,如果没有高人带,靠自己摸索,黄花菜都凉了。 常...

  • docker安装fastdfs

    作者时间雨中星辰2021-06-20 1. 创建专用网络 1. 准备配置文件 3. 修改fdfs_conf的配置文...

  • 情绪即人生(蜕变营Day2)

    2021-06-20 宇宙公民高效阅读蜕变营 Day2 今天自动5点多自动醒来,比起国内5:30上课,多了2个小时...

  • 不想通情达理,不想忍耐

    幸福日志2021-06-20 周日 晴 不想讲理,不想通情达理,不想忍耐,不想和公婆一起住,不想和公婆一起吃饭。 ...

  • #Dairy228 压力与焦虑

    2021-06-20 晴 周日 气温还是挺高,但是在慢慢下降。九点多出门走走外边还是挺凉爽的。就家里闷热。 额,市...

  • 【餐饮100问】21.怎么判断项目该不该做?

    Day232 2021-06-20 今天看到一个问题是这样的: 有一个投资项目机会,估计可以做到年销售1000万元...

  • 【点绛唇】父亲节有感

    【点绛唇】父亲节有感 (2021-06-20)犹记椿萱,温衾扇席祛寒暑。今思鸦哺,俯仰无寻处。逝水流年,倦旅凭谁诉...

  • 父亲的另一面

    父亲的另一面 原创淇玥坐南朝北望东听西2021-06-20 18:42 收录于话题 #淇玥的原作13个 #柴米油盐...

网友评论

      本文标题:2021-06-20

      本文链接:https://www.haomeiwen.com/subject/shfsyltx.html