ants:高性能的 goroutine 池库
目录
ants 是一个高性能的 goroutine 池库,用于管理和复用 goroutine,可以有效减少 goroutine 创建和销毁的开销,提高程序性能。下面详细介绍 ants 的使用方法。
1. 安装
首先安装 ants 库:
go get -u github.com/panjf2000/ants/v2
2. 基本使用
2.1 创建 goroutine 池
package main
import (
"fmt"
"sync"
"time"
"github.com/panjf2000/ants/v2"
)
func demoFunc() {
time.Sleep(10 * time.Millisecond)
fmt.Println("Hello World!")
}
func main() {
defer ants.Release()
runTimes := 1000
// 使用公共池
var wg sync.WaitGroup
syncCalculateSum := func() {
demoFunc()
wg.Done()
}
for i := 0; i < runTimes; i++ {
wg.Add(1)
_ = ants.Submit(syncCalculateSum)
}
wg.Wait()
fmt.Printf("running goroutines: %d\n", ants.Running())
fmt.Printf("finish all tasks.\n")
}
2.2 创建带容量的池
func main() {
// 设置池容量为10
p, _ := ants.NewPool(10)
defer p.Release()
for i := 0; i < 100; i++ {
p.Submit(func() {
fmt.Printf("Task %d is running\n", i)
time.Sleep(1 * time.Second)
})
}
// 等待所有任务完成
time.Sleep(5 * time.Second)
}
3. 高级功能
3.1 带参数的函数
func main() {
p, _ := ants.NewPool(10)
defer p.Release()
var wg sync.WaitGroup
task := func(i int) func() {
return func() {
fmt.Printf("Task %d is running\n", i)
time.Sleep(1 * time.Second)
wg.Done()
}
}
for i := 0; i < 100; i++ {
wg.Add(1)
p.Submit(task(i))
}
wg.Wait()
}
3.2 自定义池选项
func main() {
options := ants.Options{
ExpiryDuration: 10 * time.Second, // worker的过期时间
PreAlloc: true, // 是否预分配内存
Nonblocking: false, // 是否非阻塞模式
MaxBlockingTasks: 100, // 最大阻塞任务数
PanicHandler: func(interface{}) { // panic处理函数
fmt.Println("Recover from panic")
},
}
p, _ := ants.NewPoolWithOptions(1000, options)
defer p.Release()
// 使用池...
}
3.3 非阻塞模式
func main() {
p, _ := ants.NewPool(2, ants.WithNonblocking(true))
defer p.Release()
for i := 0; i < 5; i++ {
err := p.Submit(func() {
time.Sleep(1 * time.Second)
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
})
if err != nil {
fmt.Printf("task %d submit failed: %v\n", i, err)
}
}
time.Sleep(3 * time.Second)
}
4. 性能调优
4.1 池大小设置
- 计算密集型任务:建议设置为 CPU 核心数
- IO密集型任务:可以设置更大的值,如 CPU 核心数的 2-5 倍
p, _ := ants.NewPool(runtime.NumCPU())
4.2 监控池状态
fmt.Printf("Pool Capacity: %d\n", p.Cap())
fmt.Printf("Running Goroutines: %d\n", p.Running())
fmt.Printf("Free Goroutines: %d\n", p.Free())
5. 注意事项
- 及时释放池:使用
defer p.Release()确保池被正确释放 - 错误处理:检查
Submit方法的返回值,处理可能的错误 - 任务隔离:池中的任务应该是相互独立的,避免共享状态
- panic处理:为池设置
PanicHandler防止单个任务 panic 影响整个程序
6. 完整示例
package main
import (
"fmt"
"sync"
"time"
"github.com/panjf2000/ants/v2"
)
func main() {
// 创建带选项的池
p, err := ants.NewPoolWithOptions(10, ants.Options{
ExpiryDuration: time.Minute,
PreAlloc: true,
PanicHandler: func(recovered interface{}) {
fmt.Printf("Recovered from panic: %v\n", recovered)
},
})
if err != nil {
panic(err)
}
defer p.Release()
var wg sync.WaitGroup
// 带参数的任务
task := func(id int) {
defer wg.Done()
fmt.Printf("Task %d started\n", id)
time.Sleep(time.Second)
if id == 5 {
panic("simulated panic")
}
fmt.Printf("Task %d completed\n", id)
}
// 提交任务
for i := 0; i < 20; i++ {
wg.Add(1)
id := i
err := p.Submit(func() { task(id) })
if err != nil {
fmt.Printf("Failed to submit task %d: %v\n", id, err)
wg.Done()
}
}
wg.Wait()
// 打印池状态
fmt.Printf("Pool Capacity: %d\n", p.Cap())
fmt.Printf("Running Workers: %d\n", p.Running())
fmt.Printf("Free Workers: %d\n", p.Free())
}
ants 库通过复用 goroutine 显著提高了高并发场景下的性能,减少了内存分配和 GC 压力。合理配置池大小和选项可以使其在不同场景下发挥最佳效果。
Do not communicate by sharing memory; instead, share memory by communicating.

浙公网安备 33010602011771号