【Go语言入门学习笔记】Part19.速率控制、原子计数器、互斥锁(Mutex)、状态协程
一、前言一些关于并发操作的组件。二、学习代码速率控制package main import ( fmt time ) func main() { request : make(chan int, 5) //模拟到来五个请求 for i : 0; i 5; i { request - i * 5 } close(request) //到来五个请求后停止接收请求 limiter : time.Tick(time.Second / 5) // 200ms每次接收 //Tick底层实现就是NewTicker返回一个channel每隔200ms向channel中放入一个时间相当于无缓冲 for req : range request { -limiter //每次先等待limiter的时间间隔 fmt.Println(request:, req, time.Now()) } //突发 brustLimiter : make(chan time.Time, 3) //模拟突发请求实则为有缓冲的通道,突发计时器 for i : 0; i 3; i { //注入三个时间到brust中 brustLimiter - time.Now() } go func() { //理解为计时器协程每200ms往brustLimiter中放入一个时间保证每200ms可以处理一个请求 for t : range time.Tick(time.Second / 5) { //fmt.Println(brust time:, t, time.Now()) brustLimiter - t //每200ms向brust中放入一个时间 } }() time.Sleep(50 * time.Millisecond) //主线程睡眠50ms保证子线程有足够的时间执行 BrustRequest : make(chan int, 5) //模拟到来五个请求 for i : 0; i 5; i { BrustRequest - i * 3 } close(BrustRequest) //到来五个请求后停止接收请求 for req : range BrustRequest { -brustLimiter //每次先等待brustLimiter的时间间隔 fmt.Println(brust request:, req, time.Now()) } }原子计数器package main import ( fmt sync sync/atomic ) func main() { var count uint64 0 var wg sync.WaitGroup for i : 0; i 10; i { wg.Add(1) atomic.AddUint64(count, 1) //原子操作加1 if i 5 { fmt.Println(atomic.LoadUint64(count)) //原子操作读取count的值 } wg.Done() } wg.Wait() fmt.Println(Final count:, count) atomic.StoreUint64(count, 520) //原子操作存储count的值即赋值 }互斥锁package main import ( fmt sync ) type Container struct { mu sync.Mutex //互斥锁在一个时间段里只能有一个线程访问 counter map[string]int } func (c *Container) Increment(key string) { c.mu.Lock() defer c.mu.Unlock() c.counter[key] } func (c *Container) Get(key string) int { c.mu.Lock() defer c.mu.Unlock() return c.counter[key] } func main() { c : Container{ //互斥变量默认为可用 counter: map[string]int{key1: 0, key2: 0}, } var wg sync.WaitGroup doInc : func(key string, times int) { defer wg.Done() for i : 0; i times; i { c.Increment(key) } } wg.Add(2) go doInc(key1, 1000) go doInc(key2, 1000) wg.Wait() fmt.Println(Final counts:, c.Get(key1), c.Get(key2)) }状态协程package main import ( fmt sync ) // 状态协程对信息的操作全部封装在一个协程里有需求就向状态协程里发送消息状态协程收到消息后进行处理处理完后再返回结果给调用方 const ( Add iota //默认为0 Sub //1 Get //2 ) type Msg struct { Op int //即前面const定义的操作类型 Value int Resp chan string //用于返回结果的通道 } func Operation(balance *int, msg -chan Msg, done -chan struct{}, wg *sync.WaitGroup) { defer fmt.Println(Operation goroutine exit) defer wg.Done() for { select { case -done: return case cmd : -msg: switch cmd.Op { case Add: *balance cmd.Value cmd.Resp - Add Success case Sub: *balance - cmd.Value cmd.Resp - Sub Success case Get: cmd.Resp - fmt.Sprintf(Balance is %d, *balance) } } } } func main() { balance : 0 msg : make(chan Msg) done : make(chan struct{}) var wg sync.WaitGroup wg.Add(1) go Operation(balance, msg, done, wg) //发送加钱的消息 resp : make(chan string) msg - Msg{Op: Add, Value: 100, Resp: resp} fmt.Println(-resp) //发送减钱的消息 msg - Msg{Op: Sub, Value: 50, Resp: resp} fmt.Println(-resp) msg - Msg{Op: Get, Resp: resp} fmt.Println(-resp) // workGroup var workGroup sync.WaitGroup for i : 0; i 10; i { workGroup.Add(1) go func(i int) { defer workGroup.Done() myResp : make(chan string) msg - Msg{Op: Get, Resp: myResp} fmt.Println(-myResp, i) }(i) } workGroup.Wait() //等待所有的需求操作的协程执行完毕 close(done) //这个Done是相对优雅的退出信号 wg.Wait() }

相关新闻

2026年来内蒙游玩必吃的特色名鸡,到底选哪家才正宗好吃不踩雷

2026年来内蒙游玩必吃的特色名鸡,到底选哪家才正宗好吃不踩雷

今年内蒙旅游的热度持续走高,我身边不下10个朋友端午去乌兰察布看火山、逛草原,回来一半都吐槽:想买点当地最有名的卓资山熏鸡当伴手礼,要么买的没有烟熏味,要么咸得没法下嘴,怀疑自己买了假货。作为吃了十…

2026/10/15 15:22:47 阅读更多 →
携程被罚51.79亿,OTA告别“独家时代”

携程被罚51.79亿,OTA告别“独家时代”

“中国版Booking”的故事,该重写了。文|段泽钰编|郭梦仪中国在线旅游行业的反垄断第一案,终于尘埃落定。2026年7月25日,市场监管总局对携程滥用市场支配地位作出行政处罚,罚没款合计51.79亿元。7.5%的罚款比…

2026/10/16 17:52:28 阅读更多 →
老板IP个性化人设塑造实操思路 落地性干货分享

老板IP个性化人设塑造实操思路 落地性干货分享

短视频流量持续深耕的当下,越来越多企业老板开始重视个人IP的打造,认可其对于品牌曝光、客户信任积累、业绩转化的重要价值。但从实际落地情况来看,能够打造出有辨识度、有个性化人设,且能稳定实现业绩转化的老板账号并不多。 不少…

2026/10/17 20:10:54 阅读更多 →

最新新闻

pH敏感型IgG标记试剂:从抗体标记设计到活细胞内吞追踪的实战指南

pH敏感型IgG标记试剂:从抗体标记设计到活细胞内吞追踪的实战指南

做这行做久了会发现,抗体标记这件事,看着是"把荧光染料接到IgG上"这么一步操作,真正拉开差距的,全在细节里。普通标记试剂只能告诉你抗体在哪里,而pH敏感型IgG标记试剂能告诉你抗体到了什么环境、经历了什么…

2026/10/18 13:11:50 阅读更多 →
三个线程按序打印:信号量闸门模型与Java/C++/Python实现

三个线程按序打印:信号量闸门模型与Java/C++/Python实现

1. 三个线程按序打印,到底在考什么1.1 题目描述与表面难点这道题我先后在几个刷题平台和多轮面试复盘里见过,算是多线程入门必刷的经典题目。题目描述很短:有三个线程,分别调用同一个对象上的三个方法,每个方法内部会打…

2026/10/18 13:11:50 阅读更多 →
微信爬虫实战:公众号历史文章与阅读点赞评论抓取全链路

微信爬虫实战:公众号历史文章与阅读点赞评论抓取全链路

简介:这是一份基于 Node.js 的微信爬虫项目源码,面向需要批量采集公众号数据的开发者与数据分析人员,通过 AnyProxy 中间人代理原理抓取微信文章正文、阅读量、点赞量、在看数及评论等信息,并支持获取公众号历史文章链接。项目已适…

2026/10/18 13:11:50 阅读更多 →
HTML5移动端支付金额输入:自绘键盘与精度处理实战

HTML5移动端支付金额输入:自绘键盘与精度处理实战

简介:这份资源提供了一套可直接运行的HTML5微信支付页面键盘输入金额代码,面向移动端前端开发者、H5页面制作人员以及需要实现支付金额输入交互的初学者与进阶者。它解决的是在微信内置浏览器中,如何用自定义数字键盘完成金额输入、并配合支付…

2026/10/18 13:11:50 阅读更多 →
RTSP拉流YOLO检测:OpenCV实时视频分析与避坑指南

RTSP拉流YOLO检测:OpenCV实时视频分析与避坑指南

简介:这是一份面向视频流实时检测场景的YOLOOpenCVPython项目资源,核心解决通过RTSP协议对网络摄像头或视频流进行目标识别的问题,适合有一定Python基础的计算机视觉开发者参考。包内共14个文件,以Python脚本、YOLO模型配置、说明…

2026/10/18 13:11:50 阅读更多 →
C语言数据结构入门:从栈队列到链表的工程实践指南

C语言数据结构入门:从栈队列到链表的工程实践指南

简介:本资源是面向C语言初学者与算法进阶学习者的数据结构与算法实践合集,聚焦线性表、栈、队列、树、图、查找、排序等核心模块的C语言原生实现,覆盖高校课程教学与工程实践双重需求。压缩包共558个文件,以80个.c源码文件为主体&…

2026/10/18 13:10:49 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →