当前位置: 首页 > news >正文

Go并发编程模式与实战技巧:从Goroutine到Channel的深度实践

Go并发编程模式与实战技巧:从Goroutine到Channel的深度实践

大家好,我是迪哥。Go 的并发模型是它最迷人的特性之一,从 Goroutine 到 Channel,从 Select 到 Context,掌握这些模式能让你的代码飞起来。今天就聊聊 Go 并发编程的最佳实践。

并发基础

Goroutine

// 启动一个 Goroutine go func() { fmt.Println("Hello from goroutine") }() // 带参数的 Goroutine go sayHello("World") func sayHello(name string) { fmt.Printf("Hello, %s!\n", name) }

Channel

// 有缓冲 Channel ch := make(chan int, 100) // 发送数据 ch <- 42 // 接收数据 val := <-ch // 关闭 Channel close(ch)

Select

select { case <-ch1: fmt.Println("Received from ch1") case <-ch2: fmt.Println("Received from ch2") case <-time.After(1 * time.Second): fmt.Println("Timeout") }

并发模式

模式一:Worker Pool

func worker(id int, jobs <-chan int, results chan<- int) { for job := range jobs { fmt.Printf("Worker %d processing job %d\n", id, job) results <- job * 2 } } func main() { jobs := make(chan int, 100) results := make(chan int, 100) // 启动 3 个 worker for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // 发送 9 个任务 for j := 1; j <= 9; j++ { jobs <- j } close(jobs) // 收集结果 for r := 1; r <= 9; r++ { <-results } }

模式二:Fan-Out / Fan-In

// Fan-Out:多个 Goroutine 消费同一个 Channel func produce(ch chan<- int) { for i := 0; i < 10; i++ { ch <- i } close(ch) } func consume(id int, in <-chan int, out chan<- int) { for num := range in { out <- num * 2 } } // Fan-In:多个 Channel 的结果汇总到一个 Channel func merge(cs ...<-chan int) <-chan int { var wg sync.WaitGroup out := make(chan int) wg.Add(len(cs)) for _, c := range cs { go func(ch <-chan int) { for n := range ch { out <- n } wg.Done() }(c) } go func() { wg.Wait() close(out) }() return out }

模式三:Pipeline

func gen(nums ...int) <-chan int { out := make(chan int) go func() { for _, n := range nums { out <- n } close(out) }() return out } func sq(in <-chan int) <-chan int { out := make(chan int) go func() { for n := range in { out <- n * n } close(out) }() return out } func main() { // 生成 → 平方 → 打印 for n := range sq(gen(1, 2, 3, 4)) { fmt.Println(n) } }

模式四:Context 取消

func doWork(ctx context.Context) error { for { select { case <-ctx.Done(): return ctx.Err() default: // 正常工作 time.Sleep(100 * time.Millisecond) } } } func main() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() go doWork(ctx) }

并发安全

Mutex

type Counter struct { mu sync.Mutex value int } func (c *Counter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.value++ } func (c *Counter) Value() int { c.mu.Lock() defer c.mu.Unlock() return c.value }

Sync.Map

var cache sync.Map func getFromCache(key string) (interface{}, bool) { return cache.Load(key) } func setToCache(key string, value interface{}) { cache.Store(key, value) }

性能优化

Sync.Pool

var bufferPool = sync.Pool{ New: func() interface{} { return make([]byte, 4096) }, } func processData(data []byte) { buf := bufferPool.Get().([]byte) defer bufferPool.Put(buf) copy(buf, data) // 处理... }

避免 Goroutine 泄漏

// ❌ 泄漏:没有停止机制 go func() { for { doSomething() } }() // ✅ 正确:使用 Channel 控制 stop := make(chan struct{}) go func() { for { select { case <-stop: return default: doSomething() } } }() close(stop) // 停止 Goroutine

常见坑

原因解决方案
Goroutine 泄漏没有退出机制使用 Context 或 Channel 控制
死锁Channel 发送/接收不匹配确保发送和接收配对
数据竞争共享数据未加锁使用 Mutex 或 Channel
内存泄漏Sync.Pool 误用正确使用 Pool,避免存储指针
阻塞主协程忘记启动 Goroutine检查 go 关键字

说到并发,我家那只叫 Docker 的哈士奇最近学会了"并发抢食"——两只碗同时吃,效率翻倍,这并发能力比某些程序员还强 😂

我是迪哥,我们下期再见!

http://www.jsqmd.com/news/816364/

相关文章:

  • 强化学习实战指南:从MDP到PPO,手把手构建你的第一个智能体
  • 厂房管道工程难在哪?从新建到扩建,专业施工方的选择标准与案例解析 - 品牌2025
  • 【2026实测】直击海外检测算法:4款英文论文降AI工具盘点(附优缺点测评)
  • DALES大气模型GPU加速:OpenACC实现与优化策略
  • Taotoken的Token Plan套餐如何帮助团队更可控地管理成本
  • Reactor反应式编程实战:从基础到高级应用
  • IT30:从2000--2025年企业数字化发展4步曲
  • 【lucene】Scorer 和 BulkScorer的区别?
  • 斯科德P65证卡打印机 大尺寸工序流转卡打印机
  • 体验Taotoken官方价折扣活动带来的实际成本节省
  • 陕西播音艺考机构哪个师资力量强
  • 2026液压传感器十大品牌,广东犸力实力上榜口碑出众 - 品牌速递
  • 暗黑破坏神2角色编辑器:3分钟打造完美角色的终极免费工具
  • 5个步骤教你如何用WinUtil一站式解决Windows系统优化难题
  • 告别风扇噪音困扰:FanControl让你的电脑静音又高效
  • 2026雅思线上小班直播课程哪个好?机构与选课推荐 - 品牌2025
  • 记录数据结构与算法(顺序表)
  • OpenClaw用户通过Taotoken快速获得稳定可靠的模型服务
  • 2026安徽、安庆市陶瓷PC砖厂家实测排行:性能与性价比维度 - 奔跑123
  • NoFences:重新定义Windows桌面空间管理的开源解决方案
  • 2026 青岛纹眉机构深度测评:技术与服务双优,纹绣世家 7 家直营领跑 - 小艾信息发布
  • 矢量光速螺旋时空归一化体系全面阅读指南V2.0
  • 工业涡街流量计厂家选型深度对比 - 速递信息
  • 3步掌握BilibiliDown:从B站新手到视频收藏专家的完整指南
  • Audiveris乐谱识别:如何让纸质乐谱在10分钟内变成数字音乐?
  • 快米兔 GEO(咿嗷科技)vs 捷信 GEO vs 明轩优化 GEO —— 内容原创性与AI幻觉治理能力对比 - 速递信息
  • 04-AI产品的多巴胺开关-奖励预测误差在智能体中的应用
  • 2026年广州地区劳力士售后服务网络优化升级(最新电话及地址) - 亨得利官方服务中心
  • PNG、JPEG、WebP图片格式怎么选?从bpp(每像素位数)角度帮你算笔账
  • 2026汽车球头磨损试验机深度测评:如何匹配最佳方案? - 速递信息