通过 Channel 实现 Goroutine Pool
最近用到了 Go 从 Excel 导数据到服务器内部 用的是 http 请求
但是发现一个问题 从文件读取之后 新开 Goroutine 会无限制新增
导致全部卡在初始化请求 于是乎就卡死了
问题模拟
- 模拟代码
func main() {
pool := sync.WaitGroup{}
for i := 0; i < 500; i++ {
pool.Add(1)
go func(i int) {
resp, err := http.Get("http://ip.3322.org")
if err != nil {
fmt.Println(i, err)
} else {
defer resp.Body.Close()
result, _ := ioutil.ReadAll(resp.Body)
fmt.Println(i, string(result))
}
pool.Done()
}(i)
}
pool.Wait()
}
- 数量小的情况下 没有问题 但是数量比较大的情况 就会发现程序直接卡死 一段时间之后报错 并且没有发出任何请求
问题解决
- 实际上看的出来 是应为同时发起了太多的HTTP请求 导致系统卡死 数据没有发送
- 想到我在Java中用Thread提交请求 我就考虑 可不可限制 Goroutine 的数量
- 使用强大的百度 果然找到了大佬已经写好的协程池
- 代码如下 我加上了注释
package gopool
import (
"sync"
)
// Pool Goroutine Pool
type Pool struct {
queue chan int
wg *sync.WaitGroup
}
// New 新建一个协程池
func New(size int) *Pool {
if size <= 0 {
size = 1
}
return &Pool{
queue: make(chan int, size),
wg: &sync.WaitGroup{},
}
}
// Add 新增一个执行
func (p *Pool) Add(delta int) {
// delta为正数就添加
for i := 0; i < delta; i++ {
p.queue <- 1
}
// delta为负数就减少
for i := 0; i > delta; i-- {
<-p.queue
}
p.wg.Add(delta)
}
// Done 执行完成减一
func (p *Pool) Done() {
<-p.queue
p.wg.Done()
}
// Wait 等待Goroutine执行完毕
func (p *Pool) Wait() {
p.wg.Wait()
}
- 然后修改刚才的测试方法
package main
import (
"io/ioutil"
"log"
"net/http"
"yumc.pw/cloud/lib/gopool"
)
func main() {
// 这里限制5个并发
pool := gopool.New(5)// sync.WaitGroup{}
for i := 0; i < 500; i++ {
pool.Add(1)
go func(i int) {
resp, err := http.Get("http://ip.3322.org")
if err != nil {
fmt.Println(i, err)
} else {
defer resp.Body.Close()
result, _ := ioutil.ReadAll(resp.Body)
fmt.Println(i, string(result))
}
pool.Done()
}(i)
}
pool.Wait()
}
- 完美解决
通过 Channel 实现 Goroutine Pool的更多相关文章
- 如果裸写一个goroutine pool
引言 在上文中,我说到golang的原生http server处理client的connection的时候,每个connection起一个goroutine,这是一个相当粗暴的方法.为了感受更深一点, ...
- fasthttp 的 goroutine pool 实现探究
引言 fasthttp是一个非常优秀的web server框架,号称比官方的net/http快10倍以上.fasthttp用了很多黑魔法.俗话说,源码面前,了无秘密,我们今天通过源码来看一看她的gor ...
- goroutine pool,WaitGroup,chan 示例
服务端高并发编程经常需要写很多goroutine来服务每一个连接,如何正确使用goroutine池是又拍云的工程师们需要考虑的问题,今天这篇文章,分享给同样需要使用go语言的小伙伴们. 文/陶克路 本 ...
- golang 部分理解:关于channel 和 goroutine 例子
部分理解:关于channel 和 goroutine 例子package main import "strconv" import "fmt" func mai ...
- golang(8):channel读写 & goroutine 通信
goroutine 1.进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位 B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独 ...
- golang如何使用channel控制goroutine退出
最经典的处理方式: 在启动goroutine的时候,传递一个额外的chan型参数,用来接收退出信号,代码如下 func worker(name string, stopchan chan struct ...
- TODO:Go语言goroutine和channel使用
TODO:Go语言goroutine和channel使用 goroutine是Go语言中的轻量级线程实现,由Go语言运行时(runtime)管理.使用的时候在函数前面加"go"这个 ...
- Go语言学习笔记(七)杀手锏 Goroutine + Channel
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 Goroutine Go语言的主要的功能在于令人简易使用的并行设计,这个方法叫做Goroutine,通过Gorou ...
- go语言之行--golang核武器goroutine调度原理、channel详解
一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...
随机推荐
- 个人永久性免费-Excel催化剂功能第74波-批量排版格式利器,瞬间美化表格
PPT和WORD的世界,充满着排版的美化操作,在Excel世界同样也需要对表格.图表的美化,此篇带你进入真正的制表专家行列,使用Excel催化剂的格式管理增强功能加上对美感的艺术造诣,对Excel表格 ...
- [leetcode] #279 Perfect Squares (medium)
原题链接 题意: 给一个非整数,算出其最少可以由几个完全平方数组成(1,4,9,16……) 思路: 可以得到一个状态转移方程 dp[i] = min(dp[i], dp[i - j * j] + ) ...
- MVC+EFCore 完整教程18 -- 升级分布视图至 View Component
之前我们详细介绍过分布视图(partial view),在有一些更加复杂的场景下,.net core为我们提供了更加强大的组件 view component, 可以认为view component是 ...
- Windows 设置自启动计划任务(非登录启动)
原因:服务器会不定期重启,且重启后无人看管,不会有人去登录系统.导致我们做的一些开机启动程序失效,进而系统瘫痪. 解决方法: 自己理解,想要达到目的有两种方式:系统服务 & 计划任务配置. 计 ...
- 小白学python-day05(2)-列表及其操作
今天是day05(2),以下是学习总结 但行努力,莫问前程. --------------------------------------------------------------------- ...
- python课堂整理13---函数的作用域及匿名函数
name = 'alex' def foo(): name = 'jinling' def bar(): print(name) return bar a = foo() print(a) 阅读上述代 ...
- Spring 整合 ibatis
是的,真的是那个不好用的ibatis,不是好用的mybatis. 由于工作需要用到ibatis需要自己搭建环境,遇到了不少的坑,做一下记录. 一.环境配置 Maven JDK1.6 (非常重要,使用S ...
- Jenkins-slave实现并行的自动化测试
前言 上篇文章搭建了Jenkins-slave的分布式测试环境,我一直在想一个问题,使用这种模式能不能实现并发的自动化测试?我的想法是:同一套UI自动化的测试代码,是否能够通过一个Job绑定多个sla ...
- 关于STM32F103+ESP8266+阿里云过程之修改SDK连接至阿里云(二)
继上篇的阿里云物联云平台设置之后,接下来的工作就是对安信可官方给的sdk进行修改 安信可ESP系列集成环境,SDK,aliyun_mqtt_app,下载地址在上一篇博客,https://www.cnb ...
- 【SVN】eclipse 安装 SVN 插件
链接:eclipse中svn插件的安装 SVN 插件地址:http://subclipse.tigris.org/servlets/ProjectProcess;jsessionid=8EB28B11 ...