实现goroutine协程池

44 阅读1分钟

Goroutine具备如下两个特点

  • 体积轻量
  • 优质的GMP调度

但并不能随意的创建goroutine,因为迅速的开辟goroutine(不控制并发的 goroutine 数量 )会在短时间内占据操作系统的资源(CPU、内存、文件描述符等)。

  • CPU 使用率浮动上涨
  • Memory 占用不断上涨。
  • 主进程崩溃(被杀掉了)

这些资源实际上是所有用户态程序共享的资源,所以大批的goroutine最终引发的灾难不仅仅是自身,还会关联其他运行的程序。

所以在编写逻辑业务的时候,限制goroutine是我们必须要重视的问题。一般可以通过协程池实现。

package main

import (
   "fmt"
   "sync"
   "time"
)

type Pool struct {
   c   chan func()
   con int
   wg  sync.WaitGroup
}

func NewPool(con int) *Pool {
   return &Pool{
      c: make(chan func()),
      con: con,
   }
}

func usePool() {
   p := NewPool(5)
   for i := 0; i < p.con; i++ {
      go p.worker()
   }
   for i := 0; i < 10; i++ {
      task := func() {
         fmt.Println(time.Now())
      }
      p.c <- task
      p.wg.Add(1)
   }
   close(p.c)
   p.wg.Wait()

}

func (Pool *Pool) worker() {
   for task := range Pool.c {
      task()
      Pool.wg.Done()
   }
   fmt.Println("exit groutine")
}