使用ants并发,事半功倍
简介
ants
是一个高性能的goroutine
池,实现了对大规模goroutine
的调度管理、goroutine
复用,允许使用者在开发并发程序的时候限制goroutine
数量,复用资源,达到更高效执行任务的效果。
功能
- 自动调度海量的
goroutines
,复用goroutines
- 定期清理过期的
goroutines
,进一步节省资源 - 提供了大量有用的接口:任务提交、获取运行中的
goroutine
数量、动态调整Pool
大小、释放Pool
、重启Pool
- 优雅处理
panic
,防止程序崩溃 - 资源复用,极大节省内存使用量;在大规模批量并发任务场景下比原生
goroutine
并发具有更高的性能 - 非阻塞机制
如何运行
流程图:
示意图:
刚开始Goroutine Pool
中有四个Worker
,然后当前有六个Task任务。
然后程序运行起来之后,每个Worker
绑定一个Task
开始工作,剩余两个Task
在等待被调度。
只要Worker
有空闲的就会Fetch
一个Task
开始Running
。
所有的Task
执行完成之后,Worker
有收回进Goroutine Pool
中。
安装
- 使用
ants v1
版本:
go get -u github.com/panjf2000/ants
- 使用
ants v2
版本 (开启 GO111MODULE=on):
go get -u github.com/panjf2000/ants/v2
使用
写go
发程序的时候如果程序会启动大量的goroutine
,势必会消耗大量的系统资源(内存,CPU),通过使用ants
,可以实例化一个goroutine
池,复用goroutine
,节省资源,提升性能。
- 初始化一个
Pool
package pool import ( "github.com/panjf2000/ants" "sync" ) var ( pool *ants.Pool once sync.Once ) func InitPool(size int) { once.Do(func() { var err error pool, err = ants.NewPool(size) if err != nil { panic(err) } }) } func GetPool() *ants.Pool { return pool }
然后在main.go
中使用:
func main() { // 初始化goroutine池 pool.InitPool(100) pool.GetPool().Submit(func() { fmt.Println("task1") }) pool.GetPool().Submit(func() { fmt.Println("task2") }) pool.GetPool().Submit(func() { fmt.Println("task3") }) pool.GetPool().Submit(func() { fmt.Println("task4") }) select{} }
额外说明
Pool
创建之后,程序退出的时候得释放pool.Release()
- 也可以重启
Pool
pool.Reboot()
// 只要调用 Reboot() 方法,就可以重新激活一个之前已经被销毁掉的池,并且投入使用。 Pool
有自己的一些配置,比如PreAlloc
预分配,Logger
以及Nonblocking
等,详细请参考官网:https://github.com/panjf2000/ants/blob/dev/README_ZH.md