Go 并发编程实战:Goroutine 与 Channel 完全指南
Go 语言的并发模型基于 CSP(Communicating Sequential Processes)理论,通过 Goroutine 和 Channel 实现高效并发。本文深入讲解 Go 并发编程的核心概念和实战模式。
🚀 Goroutine:轻量级线程
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 3; i++ {
fmt.Println(s)
time.Sleep(100 * time.Millisecond)
}
}
func main() {
go say("world") // 启动 goroutine
say("hello")
}
📡 Channel:Goroutine 之间的通信
// 创建 channel
ch := make(chan string)
// 发送数据
go func() {
ch <- "Hello Go"
}()
// 接收数据
msg := <-ch
fmt.Println(msg)
🔄 带缓冲的 Channel
ch := make(chan int, 3) // 缓冲大小为 3
ch <- 1
ch <- 2
ch <- 3
// ch <- 4 // 阻塞,直到有空间
📊 Select 多路复用
select {
case msg1 := <-ch1:
fmt.Println("Received", msg1)
case msg2 := <-ch2:
fmt.Println("Received", msg2)
case <-time.After(1 * time.Second):
fmt.Println("Timeout")
default:
fmt.Println("No message")
}
🔒 Mutex:互斥锁
import "sync"
var (
counter int
mu sync.Mutex
)
func increment() {
mu.Lock()
defer mu.Unlock()
counter++
}
🔧 常用并发模式
1. Worker Pool
jobs := make(chan int, 100)
results := make(chan int, 100)
// 启动 3 个 worker
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// 发送任务
for j := 1; j <= 9; j++ {
jobs <- j
}
close(jobs)
2. Fan-out / Fan-in
多个 goroutine 处理同一个 channel(fan-out),结果汇总到一个 channel(fan-in)。
⚠️ 常见陷阱
- 死锁:确保所有 goroutine 能正确退出
- 资源泄漏:使用 context 控制 goroutine 生命周期
- 竞态条件:使用 race detector 检测(
go run -race)
总结:Go 的并发模型简单而强大。掌握 Goroutine、Channel、Select 和常用并发模式,能编写出高效、可维护的并发程序。
本文整理自 Go 官方文档及并发编程实战指南