惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Vercel News
Vercel News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
Check Point Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
The Hacker News
The Hacker News
L
LINUX DO - 热门话题
T
Tenable Blog
Hugging Face - Blog
Hugging Face - Blog
Google Online Security Blog
Google Online Security Blog
博客园 - Franky
P
Proofpoint News Feed
H
Hacker News: Front Page
P
Privacy & Cybersecurity Law Blog
月光博客
月光博客
P
Proofpoint News Feed
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
博客园_首页
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
CERT Recently Published Vulnerability Notes
Forbes - Security
Forbes - Security
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Attack and Defense Labs
Attack and Defense Labs
N
News and Events Feed by Topic
博客园 - 叶小钗
T
Threat Research - Cisco Blogs
aimingoo的专栏
aimingoo的专栏
D
Darknet – Hacking Tools, Hacker News & Cyber Security
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hacker News - Newest:
Hacker News - Newest: "LLM"
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
O
OpenAI News
G
Google Developers Blog
Martin Fowler
Martin Fowler
罗磊的独立博客
S
SegmentFault 最新的问题
T
Tor Project blog
量子位

博客园 - 干炸小黄鱼

timex 处理时间戳 gorm-gen go 雪花算法 golang每日一库--json解析库gjson python高级编程-asyncio python高级编程-condition python高级编程-event python装饰器-自动重试 EAP系统 go实现实现 SECS/GEM 协议 设备通信协议 SECS go项目使用Jenkins进行CICD go操作ES mongo db聚合查询 go如何使用mongodb Apache ShardingSphere paxos and raft (分布式一致性算法) go使用zookeeper分布式锁以及和redis差异 go使用 seata 示例 Alibaba 分布式事务 Seata go中使用saga go中使用TCC示例 分布式事务TCC 熔断器 Hystrix OR Sentinel k8s下部署consul and etcd Consul OR Etcd 【力扣hot100】双指针-盛水最多的容器 【力扣hot100】滑动窗口-最小覆盖子串 shell脚本合集 分布式id生成器 springboot通用CURD Python PB级检索系统架构设计 rancher 在三台机器搭建k8s集群 python ssh clinet 数据库排序Null值字段靠后/靠前 常规web项目 docker-compose 例子 手搓一个验证码 使用itertools 中的groupby 对字典数组进行分组后排序 使用开源库 geoip2 获取某ip的经纬度地理信息 python中 apscheduler.schedulers.blocking.BlockingScheduler 定时执行任务 简单的python web项目的docker-compose.yml 示例 python和sliver交互 golang sliver二次开发自定义命令(格式乱后面再调) pydantic做参数校验 基于rancher部署k8s 地理位置相关基础数据 flask migrate时报错 Can't locate revision identified by '3d80e4c025df'
golang每日一库--协程池库ants
干炸小黄鱼 · 2026-05-15 · via 博客园 - 干炸小黄鱼

ants 是 Go 语言中一个非常流行的高性能 Goroutine(协程)池库。它的核心作用是管理和复用 Goroutine,避免在高并发场景下因无限制地创建和销毁协程而导致系统资源耗尽、内存飙升或 GC(垃圾回收)压力过大。

以下是关于 ants 库的详细介绍与使用指南:

📦 安装与基础使用

首先,通过以下命令安装 ants

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

ants 提供了两种主要的使用模式:普通协程池带函数的协程池

1. 普通协程池 (NewPool)

适用于提交任意无参数的函数作为任务。通常需要结合 sync.WaitGroup 来同步等待所有任务完成。

package main

import (
	"fmt"
	"sync"
	"time"

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

func main() {
	var wg sync.WaitGroup
	// 创建一个容量为 10 的协程池
	pool, _ := ants.NewPool(10)
	defer pool.Release() // 确保程序结束时释放池资源

	for i := 0; i < 20; i++ {
		wg.Add(1)
		// 注意闭包传参问题,将 i 赋值给局部变量
		idx := i
		pool.Submit(func() {
			defer wg.Done()
			fmt.Printf("Task %d is running\n", idx)
			time.Sleep(time.Second) // 模拟耗时操作
		})
	}
	
	wg.Wait()
	fmt.Println("All tasks finished")
}

2. 带函数的协程池 (NewPoolWithFunc)

适用于需要向任务传递参数的场景。通过预定义一个处理函数,提交任务时直接传入参数即可,无需频繁创建闭包,性能更高。

package main

import (
	"fmt"
	"time"

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

func main() {
	// 定义一个处理任务的函数
	taskFunc := func(i interface{}) {
		n := i.(int)
		fmt.Printf("Task with param %d is running\n", n)
		time.Sleep(time.Second)
	}

	// 创建一个带函数的协程池
	pool, _ := ants.NewPoolWithFunc(10, taskFunc)
	defer pool.Release()

	for i := 0; i < 20; i++ {
		// 使用 Invoke 提交带有参数的任务
		pool.Invoke(i)
	}

	// 等待所有任务执行完毕
	pool.Wait() 
	fmt.Println("All tasks finished")
}

⚙️ 高级配置选项

在创建协程池时,ants 支持多种自定义配置来满足不同的业务需求:

  • 动态调整容量 (Tune):可以在运行时动态改变协程池的大小,适应系统负载的变化。
    pool.Tune(20) // 将池容量调整为 20
    
  • 预分配 Goroutine (WithPreAlloc):如果在高并发启动时希望立即拥有指定数量的工作协程,可以开启此选项,减少初期的调度延迟。
    pool, _ := ants.NewPool(10, ants.WithPreAlloc(true))
    
  • 非阻塞模式 (WithNonblocking):默认情况下,当池满时新任务会阻塞等待。开启非阻塞模式后,如果池已满,提交任务会直接返回错误 (ants.ErrPoolOverload)。
    pool, _ := ants.NewPool(10, ants.WithNonblocking(true))
    
  • 自定义 Panic 处理器 (WithPanicHandler):防止某个任务发生 panic 导致整个协程崩溃。你可以自定义捕获和处理逻辑。
    pool, _ := ants.NewPool(10, ants.WithPanicHandler(func(err interface{}) {
        fmt.Println("Recovered from panic:", err)
    }))
    
  • 设置空闲超时时间 (WithExpiryDuration):控制空闲的 worker 存活多久后被自动清理,以释放内存。

📊 常用监控方法

ants 提供了丰富的接口来获取协程池的实时状态,方便进行监控和调试:

方法 说明
pool.Running() 获取当前正在工作的 Goroutine 数量
pool.Free() 获取当前池中空闲可用的 Goroutine 数量
pool.Cap() 获取协程池的最大容量
pool.Wait() 仅在使用 NewPoolWithFunc 时可用,用于阻塞等待所有任务完成

💡 使用注意事项

  1. 及时释放资源:务必使用 defer pool.Release() 来关闭协程池。一旦调用 Release(),该池将无法再接受新的任务,否则会触发 panic。
  2. 合理设置池大小:根据服务器的 CPU 核心数以及任务是 I/O 密集型还是计算密集型来设定合理的池容量,并非越大越好。
  3. 避免长任务阻塞:如果某个任务执行时间极长,会一直占用池中的一个 worker,可能导致后续任务排队甚至拖垮整体吞吐量。
  4. 闭包传参陷阱:在使用 Submit 提交任务时,如果是循环提交,一定要注意 Go 语言闭包的变量捕获问题(建议使用局部变量接收循环变量),否则可能导致多个任务拿到相同的参数。