素手烹茶|- 高性能低损耗的 Goroutine 池,Ants( 二 )


除了使用默认的工作池外 , 我们还可以自己实例化一个工作池 , 并提供容量和任务函数 , 使用NewPoolWithFunc简单完成goroutine池的创建:
packagemainimport("fmt""sync""sync/atomic""time""github.com/panjf2000/ants/v2")varsumint32funcmyFunc(iinterface{}){n:=i.(int32)atomic.AddInt32(&sum,n)fmt.Printf("runwith%dn",n)}funcmain(){runTimes:=1000//创建一个容量为10的goroutine池p,_:=ants.NewPoolWithFunc(10,func(iinterface{}){myFunc(i)wg.Done()})deferp.Release()fori:=0;i<runTimes;i++{wg.Add(1)_=p.Invoke(int32(i))}wg.Wait()fmt.Printf("runninggoroutines:%dn",p.Running())fmt.Printf("finishalltasks,resultis%dn",sum)}可以看到 , 使用ants.NewPoolWithFunc , 创建了一个自定义容量和任务的函数工作池 , 任务函数可以提供一个interface{}参数 , 方便传递数据 。 然后 , 通过函数工作池的Invoke接口 , 完成任务参数的传递和任务的提交 。 在这个例子中 , 实现了从0到1000的并发求和 , 最终打印出计算结果 。
此外 , 我们还可以使用最基础的方法NewPool来进行ants.Pool结构的实例化:
p,_:=ants.NewPool(10000)NewPool的函数签名如下:
funcNewPool(sizeint,options...Option)(*Pool,error)其接收一个容量参数 , 以及其他配置参数 , 返回指向Pool类型实例的指针和错误 。 我们可以使用options参数进行更为细化的配置 , 配置参数包括:
ExpiryDuration:清理goroutine的时间间隔 。 每隔一段时间 , Ants就会对池中未被使用的goroutine进行清理 , 减少内存占用;PreAlloc:是否在初始化工作池时预分配内存 。 对于一个超大容量 , 且任务耗时长的工作池来说 , 预分配内存可以大幅降低goroutine池中的内存重新分配损耗;MaxBlockingTasks:阻塞任务的最大数 , 0代表无限制;Nonblocking:工作池是否是非阻塞的 , 这决定了Pool.Submit接口在提交任务时是否会被阻塞;PanicHandler:任务崩溃时的处理函数;Logger:日志记录器这些参数既可以在初始化的时候通过Option传递 , 也可以使用链式调用的方法实现配置叠加 , 利用WithExpiryDuration、WithPreAlloc等方法实现 。
Ants的工作池的容量需要在初始化的时候提供 , 但它并不是一成不变的 , 可以通过Tune接口实现goroutine池容量的动态调整:
pool.Tune(1000)pool.Tune(100000)这个方法时线程安全的 , 不必担心动态调整带来的数据并发问题 。
在使用完成后 , 需要对工作池进行资源释放 , 一般通过defer机制调用:
pool.Release()也可以通过Reboot方法 , 把一个已经释放资源被销毁的池重新激活 , 投入使用:
pool.Reboot()Ants以其高性能和低消耗著称 , 自然有测试依据 。 项目作者进行了1000万大规模并发任务执行的性能测试 , Ants使用70万的goroutine就完成了全部任务 , 执行速度比原生goroutine提高了100% , 且内存消耗保持在不使用Pool的40% 。 此外 , 还进行了吞吐量测试 , 使用Ants的吞吐性能达到了原生goroutine的2到6倍 , 而内存消耗则达到10到20倍的降低 。 从测试结果来看 , Ants的高性能特性名不虚传 。
总结【素手烹茶|- 高性能低损耗的 Goroutine 池,Ants】Ants作为一个高性能goroutine池 , 提供了比原生goroutine实现更为高级的调度管理和复用机制 , 抽象层次更高 , 且充分利用池化策略 , 使用尽可能少的goroutine数量和内存占用 , 以更快的速度完成并发任务的执行 , 在大规模和高吞吐场景下 , 具备很强的性能优势 。 Ants项目代码整洁 , 注释详尽 , 文档丰富 , 对于goroutine并发模型有较深的理解 , 对相关领域感兴趣的开发者可以进行参考学习 。