Golang 中的并发模型主要有以下几种:
- Goroutine:Goroutine 是 Golang 并发的基本单元,相当于轻量级线程。程序启动后默认就有一个 Goroutine,通过 go 关键字可以启动新的 Goroutine。
- Channel:Channel 是用来在 Goroutine 之间进行通讯的机制。Channel 可用于同步,控制 Goroutine 的并发数量或者广播事件等。
- Mutex:Mutex 是用来锁住共享资源的机制,用于保证同一时间仅有一个 Goroutine 可以访问该资源。
- WaitGroup:WaitGroup 用于等待一组 Goroutine 结束。主 Goroutine 会调用 Add() 方法将 WaitGroup 的计数器加 1,然后启动一个新 Goroutine。新启动的 Goroutine 在结束时会调用 Done() 方法将计数器减 1。主 Goroutine 还会调用 Wait() 方法阻塞自己并等待计数器归零。
- Once:Once 用于只运行一次代码块(初始化操作)。如果 Go 程序中有一段代码只希望执行一次,可以使用 Once 机制来保证。
- Context:Context 用于设置超时、取消信号以及传递 request 相关值等,常用于 Goroutine 之间识别比较复杂的信号。
Golang 实现并发的主要方式是 CSP(Communicating Sequential Processes)模式,也就是通过 Channel 进行不同 Goroutine 之间的通信协作。
例如:
func main() {
var wg sync.WaitGroup
// WaitGroup
wg.Add(1)
go doSomething(&wg) // Goroutine
channel := make(chan int)
// Channel
go func() {
// ......
channel <- 1 // 发送信号
}()
select {
case <-channel:
// ......
case <-time.After(time.Second * 1):
// 超时处理
}
once := sync.Once{}
// Once
onceBody := func() {
fmt.Println("Only once")
}
once.Do(onceBody)
once.Do(onceBody)
}
func doSomething(wg *sync.WaitGroup) {
// ......
wg.Done() // 计数器减1
}
Golang 的并发模型具有简单高效的特点,通过 Goroutine、Channel 等机制可以轻松实现并行计算与通信,构建高性能的并发程序。这也是 Golang 受欢迎的原因之一。