简介
ants
是一个高性能的 goroutine 池,实现了对大规模 goroutine 的调度管理、goroutine 复用,允许使用者在开发并发程序的时候限制 goroutine 数量,复用资源,达到更高效执行任务的效果。goroutine相比于线程来说,有着更轻量、资源占用更少、切换速度更快、无线程上下文切换开销更少等优势,但是也是不能无节制的创建使用。默认每个 goroutine 占用 8KB 内存,如果数量太多没有及时回收,也会使系统的内存资源耗尽。通过使用ants
,可以实例化一个 goroutine 池,复用 goroutine ,节省资源,提升性能
安装
go get -u github.com/panjf2000/ants/v2
基础使用
package main
import (
"fmt"
"github.com/panjf2000/ants/v2"
"log"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
// 生成一个具有特定函数的goroutine池 容量为10
p, err := ants.NewPoolWithFunc(10, func(i interface{}) {
taskFunc(i.(int))
wg.Done()
})
if err != nil {
log.Fatal("goroutine pool create err:", err)
}
defer p.Release() // 函数结束后关闭此池并释放工作队列
for i := 0; i < 1000; i++ {
wg.Add(1) // 每执行一次进行+1计数
_ = p.Invoke(i) // 提交一个任务到创建的goroutine池中
}
wg.Wait() // 阻塞等待任务执行完成
}
// taskFunc 执行耗时任务
func taskFunc(i int) {
time.Sleep(2 * time.Second) // 模拟耗时任务
fmt.Println("输出:", i)
}
上面是一个基本的使用案例,协程池去执行特定的任务函数,根据系统的性能去调整协程池的容量去达到最佳的运行效果
传递带参数的函数进入协程池
package main
import (
"fmt"
"github.com/panjf2000/ants/v2"
"log"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
// 生成一个自定义goroutine池 容量为10
p, err := ants.NewPool(10)
if err != nil {
log.Fatal("goroutine pool create err:", err)
}
defer p.Release() // 函数结束后关闭此池并释放工作队列
for i := 0; i < 1000; i++ {
wg.Add(1)
_ = p.Submit(taskFunc(i, &wg))
}
wg.Wait() // 阻塞等待任务执行完成
}
// taskFunc 执行耗时任务
func taskFunc(i int, wg *sync.WaitGroup) func() {
return func() {
time.Sleep(2 * time.Second) // 模拟耗时任务
fmt.Println("输出:", i)
wg.Done()
}
}
创建协程池的配置参数
- ExpiryDuration:清理 goroutine 的时间间隔。每隔一段时间,Ants 就会对池中未被使用的 goroutine 进行清理,减少内存占用
- PreAlloc:是否在初始化工作池时预分配内存。对于一个超大容量,且任务耗时长的工作池来说,预分配内存可以大幅降低 goroutine 池中的内存重新分配损耗
- MaxBlockingTasks:阻塞任务的最大数,0代表无限制
- Nonblocking:工作池是否是非阻塞的,这决定了 Pool.Submit 接口在提交任务时是否会被阻塞
- PanicHandler:任务崩溃时的处理函数
- Logger:日志记录器