Goroutine 最大数量的限制

简介: Goroutine 最大数量的限制

前言


最近有个朋友, 刚入职没多久就被组长叼了, 原因是他在业务场景中开Goroutine导致测试服务器资源占用过大, 其他服务都崩了…


场景类似于监听区块链交易, 对每个区块进行轮询处理每笔交易, 他直接循环开Goroutine处理每笔交易, 数据大了goroutine开的太多导致资源占用过大, 导致了这场悲剧;


工作中我们需要开Goroutine来提高代码处理的效率, 但也不能滥用, 需要对它进行一定限制, 保证资源占用在可控范围内, 所以我们需要对项目中Goroutine的数量进行限制, 用channel就可以很好的做到;


正文


直接上代码

gopool

package gopool
import "sync"
type Pool struct {
  wg    sync.WaitGroup
  queue chan struct{}
}
// NewGoPool 实例化一个go程池
func NewGoPool(i int) *Pool {
  if i < 1 {
    i = 1
  }
  return &Pool{queue: make(chan struct{}, i)}
}
// Add 添加
func (p *Pool) Add() {
  p.queue <- struct{}{}
  p.wg.Add(1)
}
// Done 释放
func (p *Pool) Done() {
  p.wg.Done()
  <-p.queue
}
// Wait 等待
func (p *Pool) Wait() {
  p.wg.Wait()
}

test

package gopool
import (
  "fmt"
  "runtime"
  "testing"
  "time"
)
func TestNewGoPool(t *testing.T) {
  defaultNum := runtime.NumGoroutine()
  p := NewGoPool(2)
  for i := 0; i < 100; i++ {
    p.Add()
    go func() {
      defer p.Done()
      time.Sleep(1 * time.Second)
      fmt.Println("go routine num: ", runtime.NumGoroutine()-defaultNum)
    }()
  }
  p.Wait()
  fmt.Println("go routine num: ", runtime.NumGoroutine())
}


代码都在我的个人项目 fly 中, 里面封装了一些常用的组件和应用示例, 欢迎大家 star / 提 Issues;

项目瓶颈期了…

目录
相关文章
|
存储 算法 Java
线程池最佳线程数量到底要如何配置?
线程池最佳线程数量到底要如何配置?
线程池最佳线程数量到底要如何配置?
|
10月前
|
Linux Go 调度
Go 协程为什么比进程和线程占用的系统资源低?
Go 协程为什么比进程和线程占用的系统资源低?
51 0
|
11月前
|
缓存 Go
控制goroutine 的并发执行数量
控制goroutine 的并发执行数量
120 0
|
3月前
|
Java
线程数设置
线程数设置
52 0
|
11月前
goroutine+channel实现对多个goroutine的顺序执行
goroutine+channel实现对多个goroutine的顺序执行
使用ThreadPoolExecutor,当提交线程超过maximumPoolSize 会阻塞主线程吗?
使用ThreadPoolExecutor,当提交线程超过maximumPoolSize 会阻塞主线程吗?
145 0
使用ThreadPoolExecutor,当提交线程超过maximumPoolSize 会阻塞主线程吗?
|
Java 程序员 Go
grpool goroutine池详解 | 协程管理
goroutine协程非常轻量级,这也是为什么go支持高并发,但是goroutine频繁创建销毁对GC的压力比较大。
154 0
grpool goroutine池详解 | 协程管理
|
Java
180724-统计JVM进程中线程数两种方式小记
/proc 目录以可读文本文件形式输出,提供现有进程和系统硬件相关的信息如 CPU、中断、内存、磁盘等等
543 0
180724-统计JVM进程中线程数两种方式小记
控制并发线程数的Semaphore
控制并发线程数的Semaphore
108 0