1,为什么要控制goroutine的数量?

goroutine固然好,但是数量太多了,往往会带来很多麻烦,比如耗尽系统资源导致程序崩溃,或者CPU使用率过高导致系统忙不过来。比如:

 for i:=; i < ; i++ {
go work()
}

2,用什么方法控制goroutine的数量?

要在每一次执行go之前判断goroutine的数量,如果数量超了,就要阻塞go的执行。第一时间想到的就是使用通道。每次执行的go之前向通道写入值,直到通道满的时候就阻塞了,如下:

 var ch chan int

 func work() {
//do something
<-ch
} func main() {
ch = make(chan int, )
for i:=; i < ; i++ {
ch <-
go work()
}
}

这样每次同时运行的goroutine就被限制为10个了。但是新的问题出现了,因为并不是所有的goroutine都执行完了,在main函数退出之后,还有一些goroutine没有执行完就被强制结束了。这个时候我们就需要用到sync.WaitGroup。使用WaitGroup等待所有的goroutine退出。如下:

 var wg *sync.WaitGroup

 func work() {
defer wg.Done()
//do something
} func main() {
wg = &sync.WaitGroup{}
for i:=; i < ; i++ {
wg.Add()
go work()
}
wg.Wait()//等待所有goroutine退出
}

3,优雅的使用并控制goroutine的数量

综上所述,我们封装一下,代码如下:

 package gpool

 import (
"sync"
) type pool struct {
queue chan int
wg *sync.WaitGroup
} func New(size int) *pool {
if size <= {
size =
}
return &pool{
queue: make(chan int, size),
wg: &sync.WaitGroup{},
}
} func (p *pool) Add(delta int) {
for i := ; i < delta; i++ {
p.queue <-
}
for i := ; i > delta; i-- {
<-p.queue
}
p.wg.Add(delta)
} func (p *pool) Done() {
<-p.queue
p.wg.Done()
} func (p *pool) Wait() {
p.wg.Wait()
}

来段测试代码:

 package gpool_test

 import (
"runtime"
"testing"
"time"
"gpool"
) func Test_Example(t *testing.T) {
pool := gpool.New()
println(runtime.NumGoroutine())
for i := ; i < ; i++ {
pool.Add()
go func() {
time.Sleep(time.Second)
println(runtime.NumGoroutine())
pool.Done()
}()
}
pool.Wait()
println(runtime.NumGoroutine())
}

good job,Over~

如何优雅的控制goroutine的数量的更多相关文章

  1. go中控制goroutine数量

    控制goroutine数量 前言 控制goroutine的数量 通过channel+sync 使用semaphore 线程池 几个开源的线程池的设计 fasthttp中的协程池实现 Start Sto ...

  2. Java--Semaphore控制并发线程数量

    package com; import java.util.concurrent.Semaphore; /** * Created by yangyu on 16/11/28. */ /** * Se ...

  3. Golang控制goroutine的启动与关闭

    最近在用golang做项目的时候,使用到了goroutine.在golang中启动协程非常方便,只需要加一个go关键字: go myfunc(){ //do something }() 但是对于一些长 ...

  4. 深度分析如何在Hadoop中控制Map的数量

    深度分析如何在Hadoop中控制Map的数量 guibin.beijing@gmail.com 很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数 ...

  5. 一文带你更方便的控制 goroutine

    上一篇我们讲了 go-zero 中的并发工具包 core/syncx. 从整体分析来看,并发组件主要通过 channel + mutex 控制程序中协程之间沟通. Do not communicate ...

  6. private关键字实现控制新建类数量

    private关键字作为一个重要的关键字,我们在开发中会经常用到,可是你有没有想过通过private关键字我们可以创建一个别人无法通过new来新建的类呢?下面我们就来看一下: package retu ...

  7. mapreduce中控制mapper的数量

    很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数决定.在默认情况下,最终input占据了多少block,就应该启动多少个Mapper.如果输入的 ...

  8. 深度分析如何在Hadoop中控制Map的数量(摘抄)

    很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数决定.在默认情况下,最终input占据了多少block,就应该启动多少个Mapper.如果输入的 ...

  9. Smarty控制foreach输出数量

    最近在搞ecshop,ecshop用的是smarty.在首页中想要修改展示的商品数量,但是用的是foreach,让我无从下手,在网上找了好久终于找到解决方案. <!--{foreach name ...

随机推荐

  1. 利用HttpURLConnection发送post请求上传多个文件

    本文要用java.net.HttpURLConnection来实现多个文件上传 1. 研究 form 表单到底封装了什么样的信息发送到servlet. 假如我参数写的内容是hello word,然后二 ...

  2. Codeforces Beta Round #27 E. Number With The Given Amount Of Divisors 含n个约数最小数

    http://codeforces.com/problemset/problem/27/E RT,求含n个约数的最小的数 我们设答案p = 2^t1 * 3^t2 * -- * p^tk(其中p是第k ...

  3. 方案dp。。

    最近经常做到组合计数的题目,每当看到这种题目第一反应总是组合数学,然后要用到排列组合公式,以及容斥原理之类的..然后想啊想,最后还是不会做.. 但是比赛完之后一看,竟然是dp..例如前几天的口号匹配求 ...

  4. MacOS卸载Jenkins安装包

    /Library/Application\ Support/Jenkins/Uninstall.command

  5. AngularJs的MVC模式

    在AngularJs也有带有MVC模式.此时你完全可以把html的js中的Controller写到一个外部的js文件中. Ok,在ASP.NET MVC项目,打开Content目录,创建一个新文件夹A ...

  6. 全球第一开源ERP Odoo操作手册 数据库简介

    1.3 数据库简介 每一个独立核算的企业都有一套相互关联的账簿体系, 把这一套完整的账簿体系建立在计算机系统中就称为一个数据库. 一般一个企业只用一个数据库. 如果企业有几个下属的独立核算的实体,也可 ...

  7. DS博客作业03—栈和队列

    1.本周学习总结 本周学习了栈和队列两种数据结构,分别对应后进先出,先进先出两种数据操作 学会栈的特殊类型-共享栈,队列的特殊类型-循环队列的一系列操作 学会熟练使用栈和队列的STL容器,使代码简洁 ...

  8. SpringBoot配置文件application.properties详解

    喜欢的朋友可以关注下,粉丝也缺. 相信很多的码友在接触springboot时,不知道怎么去配置一些项目中需要的配置,比如数据源,tomcat调优,端口等等,下面我就给大家奉献出一些项目中常用的配置信息 ...

  9. python3模块: requests

    Python标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务. 发送G ...

  10. 【learning】 扩展欧几里得算法(扩展gcd)和乘法逆元

    有这样的问题: 给你两个整数数$(a,b)$,问你整数$x$和$y$分别取多少时,有$ax+by=gcd(x,y)$,其中$gcd(x,y)$表示$x$和$y$的最大公约数. 数据范围$a,b≤10^ ...