控制goroutine 的并发执行数量
goroutine的数量上限是1048575吗?
正常项目,协程数量超过十万就需要引起重视。如果有上百万goroutine,一般是有问题的。
但并不是说协程数量的上限是100多w
1048575的来自类似如下的demo代码:
package main
import (
"fmt"
"math"
"runtime"
"time"
)
// https://zhuanlan.zhihu.com/p/568151296
func main() {
maxCount := math.MaxInt64
for i := 0; i < maxCount; i++ {
go func(i int) {
fmt.Printf("i is: %d,goroutine num: %d\n", i, runtime.NumGoroutine())
// 模拟各种耗时较长的业务逻辑
time.Sleep(10 * time.Second)
}(i)
}
}
执行后,很快报错
panic: too many concurrent operations on a single file or socket (max 1048575)
但这个是因为fmt.Printf导致的:
对单个file/socket的并发操作数超过了系统上限,这个是标准输出造成的,具体一点,就是文件句柄数量达到限制
如下例子,去掉fmt:
package main
import (
"fmt"
"math"
"runtime"
"time"
)
func main() {
maxCount := math.MaxInt64
for i := 0; i < maxCount; i++ {
go func(i int) {
// 模拟各种耗时较长的业务逻辑
//time.Sleep(10 * time.Hour)
time.Sleep(15 * time.Second)
if i > 1300_0000 {
//if runtime.NumGoroutine() > 1000_0000 {
fmt.Println("当前协程数:", runtime.NumGoroutine())
}
}(i)
}
}
实际同一时间可以出现1000w的goroutine,可见goroutine的理论上限绝对不止100w
或者如下:
package main
import (
"fmt"
"math"
"runtime"
"time"
)
func main() {
maxCount := math.MaxInt64
for i := 0; i < maxCount; i++ {
go func(i int) {
// 模拟各种耗时较长的业务逻辑
//time.Sleep(10 * time.Hour)
time.Sleep(15 * time.Second)
//if i > 1300_0000 {
if runtime.NumGoroutine() > 800_0000 {
fmt.Println("当前协程数:", runtime.NumGoroutine())
}
}(i)
}
}
panic: too many concurrent operations on a single file or socket (max 1048575)
goroutine 1231546 [running]:
internal/poll.(*fdMutex).rwlock(0x140000a2060, 0x20?)
/Users/fliter/.g/go/src/internal/poll/fd_mutex.go:147 +0x134
internal/poll.(*FD).writeLock(...)
/Users/fliter/.g/go/src/internal/poll/fd_mutex.go:239
internal/poll.(*FD).Write(0x140000a2060, {0x14635532bc0, 0x19, 0x20})
/Users/fliter/.g/go/src/internal/poll/fd_unix.go:370 +0x48
os.(*File).write(...)
/Users/fliter/.g/go/src/os/file_posix.go:48
os.(*File).Write(0x140000a0008, {0x14635532bc0?, 0x19, 0x10412e25c?})
/Users/fliter/.g/go/src/os/file.go:175 +0x60
fmt.Fprintln({0x104168cf8, 0x140000a0008}, {0x140bde92f88, 0x2, 0x2})
/Users/fliter/.g/go/src/fmt/print.go:285 +0x74
fmt.Println(...)
/Users/fliter/.g/go/src/fmt/print.go:294
main.main.func1(0x0?)
/Users/fliter/go/src/shuang/0000/goNum.go:20 +0x150
created by main.main
/Users/fliter/go/src/shuang/0000/goNum.go:14 +0x54
exit status 2
比较奇怪的是,如果将模拟各种耗时较长的业务逻辑的time.Sleep(15 * time.Second)改为time.Sleep(10 * time.Hour),最终会因为内存过高而signal: killed。但此时goroutine数量不够多,触发不了if里面的fmt逻辑,故而不会出现panic: too many concurrent operations on a single file or socket (max 1048575)
(而休眠10几s的代码,内存到不了这么大,就已经因为fmt的问题panic了)
控制方式
使用有缓冲的channel,限制并发的协程数量
make(chan struct{}, 300) 创建缓冲区大小为 300 的 channel,在没有被接收的情况下,至多发送 300 个消息则被阻塞。
开启协程前,调用 ch <- struct{}{},若缓存区满,则阻塞。 协程任务结束,调用 <-ch 释放缓冲区。
// 通过channel来控制并发数
package main
import (
"fmt"
"math"
"runtime"
"time"
)
func main() {
ch := make(chan struct{}, 300)
maxCount := math.MaxInt64
for i := 0; i < maxCount; i++ {
ch <- struct{}{}
go func(i int) {
//fmt.Printf("i is: %d,go func num: %d\n", i, runtime.NumGoroutine())
// 模拟各种耗时较长的业务逻辑
//time.Sleep(10 * time.Hour)
time.Sleep(15 * time.Second)
//if i > 1000_0000 {
//if runtime.NumGoroutine() > 1000_0000 {
fmt.Println("当前协程数:", runtime.NumGoroutine())
//}
//读取channel数据
<-ch
}(i)
}
}
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
当前协程数: 301
...
同时只有301个协程(每15s,处理301个;限制太少,会大大增加程序执行完成需要的时间,具体限制多少,需要权衡,太大太小可能都有问题)
更多参考:
如何控制golang协程的并发数量问题[1]
golang实现并发数控制的方法[2]
golang控制并发数[3]
Golang的并发控制[4]
即所谓的
无缓冲的channel可以当成阻塞锁来使用 (Go用两个协程交替打印100以内的奇偶数)
有缓冲的channel通常可以用来控制goroutine的数量
来,控制一下 goroutine 的并发数量[5]
还有通过协程池,信号量等方式,可参考 【警惕】请勿滥用goroutine[6]
aceld-Go是否可以无限go?如何限定数量?[7]
参考资料
如何控制golang协程的并发数量问题: http://www.manongjc.com/detail/62-ixfkirkdenvuohr.html
[2]golang实现并发数控制的方法: http://www.qb5200.com/article/327027.html
[3]golang控制并发数: https://blog.csdn.net/weixin_38155824/article/details/128240704
[4]Golang的并发控制: https://blog.csdn.net/LINZEYU666/article/details/123020597
[5]来,控制一下 goroutine 的并发数量: https://eddycjy.gitbook.io/golang/di-1-ke-za-tan/control-goroutine
[6]【警惕】请勿滥用goroutine: https://juejin.cn/post/6999807716482875422#heading-5
[7]aceld-Go是否可以无限go?如何限定数量?: https://github.com/catandcoder/golang/blob/main/4%E3%80%81Go%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E6%97%A0%E9%99%90go%EF%BC%9F%E5%A6%82%E4%BD%95%E9%99%90%E5%AE%9A%E6%95%B0%E9%87%8F%EF%BC%9F.md
本文由 mdnice 多平台发布
相关文章:
控制goroutine 的并发执行数量
goroutine的数量上限是1048575吗? 正常项目,协程数量超过十万就需要引起重视。如果有上百万goroutine,一般是有问题的。 但并不是说协程数量的上限是100多w 1048575的来自类似如下的demo代码: package mainimport ( "fmt" "ma…...
深入解析即时通讯App开发中的关键技术
即时通讯App开发在现代社交和通信领域中扮演着重要的角色。随着移动设备的普及和网络的高速发展,人们对即时通讯工具的需求不断增加。本篇文章将深入探讨即时通讯App开发中的关键技术,帮助读者了解该领域的最新动态和技术趋势。 基础架构和通信协议 现…...
ClickHouse进阶(三):ClickHouse 索引
进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…...
四、MySQL(表操作)如何添加字段?修改表?删除字段?修改表名?删除表?格式化某张表?
1、添加字段 (1)基础语法: alter table 表名 add 字段名 类型名(长度) [comment注释] [约束]; (2)示例:添加nickname这个字段 2、修改表 修改表中某个字段的【数据类型】/【数据类型&字段名】 &…...
docker启动paddlespeech服务,并使用接口调用
一、检查docker容器是否启动 1.输入命令 systemctl status docker 启动 systemctl start docker 守护进程重启 sudo systemctl daemon-reload 重启docker服务 systemctl restart docker 重启docker服务 sudo service docker restart 关闭docker service docker…...
如何训练ChatGPT以生成音乐和创意艺术作品?
训练ChatGPT生成音乐和创意艺术作品是一个令人兴奋且具有挑战性的任务。这种技术,也被称为生成式艺术,涉及将人工智能(AI)模型与创意艺术的融合。在本文中,我将探讨如何训练ChatGPT以生成音乐和创意艺术作品的过程&…...
北约报告:2023-2043,下一代量子技术的发展与挑战
“当今的新技术正在以令人眼花缭乱的速度发展,我们所有人都可以在负责任且合乎道德的方式开发和部署新技术方面发挥作用。” ——这是副秘书长Mircea Geoană在2023年3月22日、在布鲁塞尔发布《北约科学技术组织2023-2043年趋势报告》时传达的信息。 Geoană先生强调…...
arm版Linux下安装es集群
背景:由于生产上网络没通,没办法,只能自己安装一个es集群的测试环境了,我的电脑是Mac M2,安装的Linux是centos7,也是arm版的。 第一步:查看自己Linux系统的版本 命令:uname -a 例如…...
vConsole调试工具的三种使用方式
1.在html页面时, 在页面引入 cdn 方式引入 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" co…...
不用订阅,不用破解,永久免费使用Axure最新版教程
首先去官网下载最新的axure,你没听错,就是最新的。 下载网址:Axure RP - UX Prototypes, Specifications, and Diagrams in One Tool 下载完后解压安装到本地,并注册属于你自己的账户,开始试用。可惜的是只有30天的试…...
合宙Air724UG LuatOS-Air LVGL API控件--复选框 (Checkbox)
复选框 (Checkbox) 复选框主要是让用户进行一些内容选择,或者同意用户协议。 示例代码 – 复选框回调函数 function event_handler(obj, event) if event lvgl.EVENT_VALUE_CHANGED then print(“State”, lvgl.checkbox_is_checked(obj)) end end – 创建复选框…...
使用nps实现内网穿透
1、介绍 当我们想把内网的一些资源暴露在公网上时,可以使用内网穿透功能。比如公司的内网服务器,部署了平时需要开发的项目,但是回到家中无法访问,就可以使用内网穿透,将公司内网的接口映射到一台公网的服务器上&a…...
时序预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测
时序预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测 目录 时序预测 | MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-BiGRU时间卷积双向门控循环单元时间序列预测&a…...
websocket和uni-app里使用websocket
一、HTTP是无状态协议 特点: 1、浏览器发送请求时,浏览器和服务器会建立一个连接。完成请求和响应。在http1.0之前,每次请求响应完毕后,会立即断开连接。在http1.1之后,当前网页的所有请求响应完毕后,才断…...
Opencv-C++笔记 (18) : 轮廓和凸包
文章目录 一、轮廓findContours发现轮廓drawContours绘制轮廓代码 二.几何及特性概括——凸包(Convex Hull)凸包概念凸包扫描算法介绍——Graham扫描算法 相关API介绍程序示例轮廓集合及特性性概括——轮廓周围绘制矩形框和圆形相关理论介绍轮廓周围绘制矩形 -API绘制步骤程序实…...
【半监督医学图像分割】2022-MedIA-UWI
【半监督医学图像分割】2022-MedIA-UWI 论文题目:Semi-supervise d me dical image segmentation via a triple d-uncertainty guided mean teacher model with contrastive learning 中文题目:基于对比学习的三维不确定性指导平均教师模型的半监督图像分…...
python发送邮件
为了安全起见,我们发送邮件需要使用tls,这样发送的内容都是加密的了,但是该工具批量发送带有自定义内容的邮件不方便,于是写了一个py脚本,使用--data参数,方便批量发送,我们的策略是每天随机发送…...
gitee上传本地项目bug
🤮这个破bug不知道浪费了多长时间,以前没有记录,每次都忘记,这次记下来 问题描述 gitee创建仓库,然后根据它提示的如下命令,但一直报错 原因分析: 把命令复制出来,粘贴到Sublime …...
自然语言处理2-NLP
目录 自然语言处理2-NLP 如何把词转换为向量 如何让向量具有语义信息 在CBOW中 在Skip-gram中 skip-gram比CBOW效果更好 CBOW和Skip-gram的算法实现 Skip-gram的理想实现 Skip-gram的实际实现 自然语言处理2-NLP 在自然语言处理任务中,词向量(…...
穿上App外衣,保持Web灵魂——PWA温故
早在2015年,设计师弗朗西斯贝里曼和Google Chrome的工程师亚历克斯罗素提出“PWA(渐进式网络应用程序)”概念,将网络之长与应用之长相结合,其核心目标就是提升 Web App 的性能,改善 Web App以媲美Native的流…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...
