golang高性能低成本goroutine池管理插件库ants的使用
Golang高性能低成本goroutine池管理插件库ants的使用
简介
ants
库实现了一个固定容量的goroutine池,可以管理和回收大量goroutine,允许开发者限制并发程序中的goroutine数量。
特性
- 自动管理和回收大量goroutine
- 定期清除过期的goroutine
- 丰富的API:提交任务、获取运行中的goroutine数量、动态调整池容量、释放池、重启池等
- 优雅处理panic,防止程序崩溃
- 内存使用高效,甚至可能比Go无限制goroutines实现更高性能
- 非阻塞机制
- 预分配内存(环形缓冲区,可选)
工作原理
流程图
活动图
安装
安装ants v1
go get -u github.com/panjf2000/ants
安装ants v2 (GO111MODULE=on)
go get -u github.com/panjf2000/ants/v2
使用示例
基本使用
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
// 使用池执行任务
for i := 0; i < runTimes; i++ {
wg.Add(1)
ants.Submit(func() {
demoFunc()
wg.Done()
})
}
wg.Wait()
fmt.Printf("running goroutines: %d\n", ants.Running())
fmt.Printf("finish all tasks.\n")
}
自定义池容量
// 创建容量为10000的池
p, _ := ants.NewPool(10000)
提交任务
// 提交任务到池
ants.Submit(func(){})
运行时调整池容量
pool.Tune(1000) // 调整容量到1000
pool.Tune(100000) // 调整容量到100000
预分配池内存
// ants会在调用ants.NewPool时预分配整个池容量
p, _ := ants.NewPool(100000, ants.WithPreAlloc(true))
释放池
pool.Release()
// 或者带超时释放
pool.ReleaseTimeout(time.Second * 3)
重启池
// 已释放的池可以通过调用Reboot()继续使用
pool.Reboot()
完整示例
package main
import (
"fmt"
"sync"
"sync/atomic"
"time"
"github.com/panjf2000/ants/v2"
)
var sum int32
func myFunc(i interface{}) {
n := i.(int32)
atomic.AddInt32(&sum, n)
fmt.Printf("run with %d\n", n)
}
func demoFunc() {
time.Sleep(10 * time.Millisecond)
fmt.Println("Hello World!")
}
func main() {
defer ants.Release()
runTimes := 1000
// 使用池的普通池
var wg sync.WaitGroup
// 使用池执行任务
for i := 0; i < runTimes; i++ {
wg.Add(1)
ants.Submit(func() {
demoFunc()
wg.Done()
})
}
wg.Wait()
fmt.Printf("running goroutines: %d\n", ants.Running())
fmt.Printf("finish all tasks.\n")
// 使用带函数的池
p, _ := ants.NewPoolWithFunc(10, func(i interface{}) {
myFunc(i)
wg.Done()
})
defer p.Release()
// 提交任务
for i := 0; i < runTimes; i++ {
wg.Add(1)
_ = p.Invoke(int32(i))
}
wg.Wait()
fmt.Printf("running goroutines: %d\n", p.Running())
fmt.Printf("finish all tasks, result is %d\n", sum)
}
注意事项
提交到ants
池的所有任务不能保证按顺序执行,因为这些任务分散在一系列并发的工作线程中,因此这些任务是并发执行的。
更多关于golang高性能低成本goroutine池管理插件库ants的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高性能低成本goroutine池管理插件库ants的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang高性能goroutine池管理库ants使用指南
ants是一个高性能且低成本的goroutine池实现,特别适合需要大量goroutine但希望控制资源消耗的场景。下面详细介绍ants的使用方法。
安装
go get -u github.com/panjf2000/ants/v2
基本使用
1. 创建goroutine池
package main
import (
"fmt"
"sync"
"time"
"github.com/panjf2000/ants/v2"
)
func demoFunc() {
time.Sleep(1 * time.Second)
fmt.Println("Hello World!")
}
func main() {
defer ants.Release()
runTimes := 1000
// 使用公共池
var wg sync.WaitGroup
for i := 0; i < runTimes; i++ {
wg.Add(1)
ants.Submit(func() {
demoFunc()
wg.Done()
})
}
wg.Wait()
fmt.Printf("running goroutines: %d\n", ants.Running())
fmt.Printf("total goroutines: %d\n", ants.Cap())
}
2. 自定义池大小
func main() {
// 设置池容量为10
p, _ := ants.NewPool(10)
defer p.Release()
for i := 0; i < 100; i++ {
p.Submit(func() {
demoFunc()
})
}
// 获取当前正在运行的goroutine数量
fmt.Printf("running goroutines: %d\n", p.Running())
}
高级特性
1. 带参数的函数
func demoFuncWithArgs(i int) {
time.Sleep(1 * time.Second)
fmt.Printf("Hello World! %d\n", i)
}
func main() {
p, _ := ants.NewPool(10)
defer p.Release()
for i := 0; i < 100; i++ {
// 使用闭包传递参数
p.Submit(func() {
demoFuncWithArgs(i)
})
}
}
2. 超时控制
func main() {
p, _ := ants.NewPool(10)
defer p.Release()
// 带超时的提交
err := p.Submit(func() {
time.Sleep(2 * time.Second)
fmt.Println("Task completed")
})
if err != nil {
fmt.Println("Submit task error:", err)
}
}
3. 动态调整池大小
func main() {
p, _ := ants.NewPool(10)
defer p.Release()
// 调整容量到20
p.Tune(20)
// 调整容量到5
p.Tune(5)
}
性能优化建议
-
合理设置池大小:根据任务类型和服务器资源设置合适的池大小
- CPU密集型任务:核心数+1
- IO密集型任务:可以设置更大一些
-
复用池:避免频繁创建和销毁池
-
错误处理:注意处理池满时的错误
-
监控指标:定期检查Running()和Cap()以调整池大小
完整示例
package main
import (
"fmt"
"sync"
"time"
"github.com/panjf2000/ants/v2"
)
func main() {
// 创建容量为100的池,预分配内存
p, _ := ants.NewPool(100, ants.WithPreAlloc(true))
defer p.Release()
var wg sync.WaitGroup
task := func(i int) func() {
return func() {
time.Sleep(100 * time.Millisecond)
fmt.Printf("Task %d done\n", i)
wg.Done()
}
}
start := time.Now()
for i := 0; i < 1000; i++ {
wg.Add(1)
p.Submit(task(i))
}
wg.Wait()
fmt.Printf("All tasks done, time elapsed: %s\n", time.Since(start))
fmt.Printf("Pool size: %d, Running workers: %d\n", p.Cap(), p.Running())
}
ants库通过复用goroutine显著降低了频繁创建和销毁goroutine的开销,特别适合高并发场景。合理使用可以显著提升程序性能并降低资源消耗。