Go 语言之所以在云计算、微服务领域如此流行,很大程度上归功于其原生支持并发的设计(CSP 模型)。Goroutine 和 Channel 是 Go 语言并发编程的两大基石。
Goroutine:轻量级线程
Goroutine 是 Go 语言中的轻量级线程实现,由 Go 运行时(Runtime)管理。Goroutine 相比操作系统线程(OS Thread)更加轻量:
- 启动成本低: Goroutine 的栈空间初始只有 2KB(可动态伸缩),而 OS 线程通常是 MB 级别。
- 切换成本低: Goroutine 的调度发生在用户态,避免了昂贵的系统调用。
启动一个 Goroutine 非常简单,只需在函数调用前加上 go 关键字:
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
Channel:通信机制
Go 语言的并发哲学是:“不要通过共享内存来通信,而要通过通信来共享内存。” Channel 就是这种哲学的体现。它是一种类型安全的管道,用于在 Goroutine 之间传递数据。
ch := make(chan int) // 创建一个 int 类型的 channel
go func() {
ch <- 42 // 发送数据
}()
v := <-ch // 接收数据
fmt.Println(v)
Select:多路复用
select 语句使一个 Goroutine 可以等待多个通信操作。select 会阻塞,直到条件分支中的某个可以继续执行,这时就会执行那个分支。
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
case <-time.After(1 * time.Second):
fmt.Println("timeout")
}
Sync 包
除了 Channel,Go 标准库 sync 包也提供了传统的并发原语,如 Mutex(互斥锁)和 WaitGroup(等待组),适用于需要精细控制共享状态的场景。

发表评论 取消回复