「GoCN酷Go推荐」协程池ants介绍

推荐理由

协程泄漏引发的血案,想必各位gopher都经历过,通过协程池限制goroutine数是一个有效避免泄漏的手段。今天介绍的ants库是公认且优秀的协程池实现。ants Github主页上的简介:

ants是一个高性能的 goroutine 池,实现了对大规模 goroutine 的调度管理,允许使用者在开发并发程序的时候限制 goroutine 数量,复用资源,达到更高效执行任务的效果。

功能介绍

  • 自动调度海量的 goroutines,复用 goroutines

  • 定期清理过期的 goroutines,进一步节省资源

  • 提供了大量有用的接口:任务提交、获取运行中的 goroutine 数量、动态调整 Pool 大小、释放 Pool、重启 Pool

  • 优雅处理 panic,防止程序崩溃

  • 资源复用,极大节省内存使用量;在大规模批量并发任务场景下比原生 goroutine 并发具有更高的性能

  • 非阻塞机制

使用指南

目前测试通过的 Golang 版本:

v1.8.x** ~ v1.16.x** 的所有版本。

安装

go get -u github.com/panjf2000/ants

使用 v2 版本 (开启 GO111MODULE=on):

go get -u github.com/panjf2000/ants/v2

代码示例

ants支持两种协程池,Pool和PoolWithFunc,差别在于,Pool每个任务是一个函数,PoolWithFunc任务函数在初始化时确定,每个任务只是不同的入参调用该函数。

Pool
import (
    "fmt"
    "sync"
    "sync/atomic"
    "time"

    "github.com/panjf2000/ants/v2"
)

func demoFunc() {
    time.Sleep(10 * time.Millisecond)
    fmt.Println("Hello World!")
}

func main() {
    // 释放ants的默认协程池
    defer ants.Release()

    var wg sync.WaitGroup
    // 任务函数
    syncCalculateSum := func() {
        demoFunc()
        wg.Done()
    }
    for i := 0; i < 100; i++ {
        wg.Add(1)
        // 提交任务到默认协程池
        _ = ants.Submit(syncCalculateSum)
    }
    wg.Wait()
    fmt.Printf("running goroutines: %d\n", ants.Running())
    fmt.Printf("finish all tasks.\n")
}
PoolWithFunc
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 main() {
    // 初始化协程池
    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协程池支持一下配置项:

  • 协程池大小设置,可通过

  • worker协程过期时间,过期后的协程会被清理

  • 内存预分配,是否初始化Pool的时候分配worker资源

  • 最大阻塞任务数,默认0,任务阻塞直到分配到worker;当非0时,达到最大任务数,不执行任务并返回overload

  • 非阻塞提交,默认否,任务无worker执行时阻塞,当为true时,无worker则立即返回overload

  • 自定义panic处理函数

  • 自定义日志函数

代码片段:

// 设置配置项
    options := Options{}
 options.ExpiryDuration = time.Duration(10) * time.Second
 options.Nonblocking = true
 options.PreAlloc = true
    // 初始化
 poolOpts, _ := NewPool(10, WithOptions(options))

以上是ants的基本使用,更详细的内容可以参考ants源码。

总结

协程池通过复用和限制goroutine数,可以减轻runtime调度压力,避免过多的gorouutine占用系统cpu和内存资源,ants作为协程池实现优秀代表,功能丰富且简单易用,推荐在适合的场景使用。

参考资料

  1. https://github.com/panjf2000/ants

  2. https://strikefreedom.top/high-performance-implementation-of-goroutine-pool

《酷Go推荐》招募:

各位Gopher同学,最近我们社区打算推出一个类似GoCN每日新闻的新栏目《酷Go推荐》,主要是每周推荐一个库或者好的项目,然后写一点这个库使用方法或者优点之类的,这样可以真正的帮助到大家能够学习到

新的库,并且知道怎么用。

大概规则和每日新闻类似,如果报名人多的话每个人一个月轮到一次,欢迎大家报名!戳「阅读原文」,即可报名

扫码也可以加入 GoCN 的大家族哟~

17cd604c361561087fede60016eee88f.png

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值