尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【Go语言入门学习笔记】Part19.速率控制、原子计数器、互斥锁(Mutex)、状态协程

【Go语言入门学习笔记】Part19.速率控制、原子计数器、互斥锁(Mutex)、状态协程
📅 发布时间:2026/7/30 6:20:07

一、前言

一些关于并发操作的组件。

二、学习代码

速率控制:

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() }

相关新闻

  • 51单片机按键计数与数码管显示:从硬件搭建到软件优化的嵌入式入门实战
  • Keil RTE实战指南:STM32开发中的软件组件管理与配置
  • Qt 6.5安卓开发环境配置全攻略:从JDK、SDK到APK打包

最新新闻

  • IIS6.0解析漏洞与PUT上传攻击:原理、复现与纵深防御实践
  • Python+Vue构建汽车推荐系统:技术选型与实战经验
  • 图片压缩工具免费jpg在线:论文投稿被卡时手机电脑对照着选 - 办公小帮手
  • Android 11+分区存储机制解析:开发者适配与高级用户访问Android/data目录全攻略
  • 2026年有哪些值得推荐的游戏BI工具
  • 30分钟快速搭建Mysql主从环境

日新闻

  • 终极TeamSpeak3音乐机器人搭建指南:5分钟实现语音聊天室音频播放
  • 广州海珠区内搬家攻略,平价靠谱搬家服务商推荐,专业打包搬运省心避坑全流程指南 - 厚道搬家
  • 大语言模型入门指南:从零到精通掌握AI核心技术的5大步骤

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号