当前位置:网站首页>【Go】如何控制协程的最大并发数
【Go】如何控制协程的最大并发数
2022-07-26 01:11:00 【ZibeSun】
【Go】如何控制协程的最大并发数
摘要
本文将讲解在Go代码中如何使用channel来限制最大并发量。
作者水平有限,有任何问题欢迎在文章下方留言!
引入-并发编程时遇到问题
前两天搬砖时遇到一个需求,需要大量请求另外一个服务获取信息。于是我便启用了多个协程并发地去发送请求,写完自测了一波,一开始请求量小还好,当请求量一多,很多请求就开始失败了,报如下错误:socket: too many open files。
出现这个报错是因为linux中某个进程打开文件数(句柄)已经达到上限,也就是说并发协程数量太多了。
下面就来讲讲如何在代码中使用channel来限制最大并发量。
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:n err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:t err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:v err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:l err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:s err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:h err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:r err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
2022-05-30T15:21:50.624+0800 ERROR project_manage/organization_service.go:156 func:GetProjectSimpleList GetStaffBaseInfoApi engName:g err:Get "http://xxx": dial tcp x.xx.xx.xx:80: socket: too many open files
使用channel限制并发数
使用channel限制并发数原理非常简单,利用了Go中channel缓冲区满时,会阻塞写入。
基本逻辑如下:
- 创建一个
channel,缓冲区设置为你想要的最大并发数,比如100。 - 每创建一个协程前,就往
channel里写入一个数值,表示占位。 - 每当一个协程执行结束时,就从
channel中读出一个数值,表示让位。 - 当当前同时在执行的协程达到最大并发数时,即
channel的缓冲区被占满,此时新的协程要执行时,占位会被阻塞,直到有其他协程退出让位后,才会执行。
此方法原理简单,代码实现起来也简单,十分优雅。不过需要注意的是,在最大并发数未触及其他限制的情况下(比如上述的同时请求数量太多,进程打开的句柄数量受限等情况),最大并发数也并不是越多,程序执行的越快,关于这个问题的讨论后续可以再写一篇文章进行深入。
具体Go代码如下所示:
func GetInfo(idList []int) error {
var wg sync.WaitGroup
// 限制最大并发数为100
limitGoroutine := make(chan int, 100)
wg.Add(len(idList))
for _, id := range idList {
// 每启动一个协程,就往channel里写入一位数
limitGoroutine <- 0
go func() {
// 并发请求获取信息
// 存入数据库
wg.Done()
// 协程执行完退出时,就从channel里读一位数
<-limitGoroutine
}()
}
wg.Wait()
return nil
}
边栏推荐
- [Code] refers to the repeated number in the offer 03 array
- Working principle of ZK rollups
- 换ip软件的用途很广及原理 动态IP更换的四种方法来保护网络隐私
- Sqli-labs Less7
- 网络性能评估工具 ping/mtr
- Subarray with 19 and K
- Game thinking 17: Road finding engine recast and detour learning II: recast navigation grid generation process and limitations
- [RTOS training camp] I2C and UART knowledge and preview arrangement + evening class questions
- If the native family is general, and the school is also a college on the rotten street, how to go on the next journey
- web中间件日志分析脚本3.0(shell脚本)
猜你喜欢

Implementation process of adding loading effect to easycvr page

Lua basic grammar

Detailed explanation of at and crontab commands of RHCE and deployment of Chrony

NLP introduction + practice: Chapter 3: gradient descent and back propagation
![[Code] refers to the repeated number in the offer 03 array](/img/83/50f5157c363d46f38f6e4ef7fae3b2.png)
[Code] refers to the repeated number in the offer 03 array

【秒杀概念】大小端

ZK-Rollups工作原理

Spine_附件皮肤
![[RTOS training camp] operation explanation, queue and ring buffer, queue - transmission data, queue - synchronization tasks and evening class questions](/img/59/0b671129e8cfaed28e2fe484ae0467.jpg)
[RTOS training camp] operation explanation, queue and ring buffer, queue - transmission data, queue - synchronization tasks and evening class questions

【纪中】2022.7.16 1432.输油管道
随机推荐
The Chinese input (Pinyin input method) component created by lvgl official +100ask enables lvgl to support Chinese input!
Arthas watch 命令查看数组中对象的属性
【秒杀概念】大小端
FastJson 处理泛型
[translation paper] analysis of land cover classification using multi wavelength lidar system (2017)
代理IP服务器如何保证自身在网络中的信息安全呢
IP地址能精确到哪步?动态IP及静态IP是什么?切换IP最常用的方法
Mmocr usage guide
腾讯员工晒出薪资:真实985毕业薪资,大家看我还有救吗?网友:日薪?
Crawler small operation
Paged query design of scenarios
游戏思考17:寻路引擎recast和detour学习二:recast导航网格生成流程及局限性
【RTOS训练营】关于上课和答疑
“元气可乐”不是终点,“中国可乐”才是
【纪中】2022.7.16 1432.输油管道
NLP introduction + practice: Chapter 3: gradient descent and back propagation
MySQL pymysql operation
[RTOS training camp] about classes and Q & A
Diablo: immortality mobile game how to open more brick moving and novice introduction brick moving strategy
How to copy and paste QT? (QClipboard)