Golang 常用的并发模型及应用案例 随着互联网技术的不断发展,现代应用程序需要具备并发、高性能和高可扩展性的特点。Go 语言作为一门高效、简洁、并发性强的编程语言,其并发模型是其最为重要的特性之一。 本文将介绍 Golang 常用的并发模型及其应用案例,让大家学习掌握并发编程的基础知识。 1. Goroutine Goroutine 是 Go 语言中最常用的并发模型,它是一种轻量级的线程,由 Go 运行时进行调度。Goroutine 可以在主线程中并发运行,充分利用 CPU 资源。 Goroutine 可以通过 go 关键字创建: ``` func main() { go func() { // goroutine 代码块 }() // 主线程代码块 } ``` Goroutine 还支持通过 channel 与其他 Goroutine 进行通信: ``` func main() { c := make(chan int) go func() { for i := 0; i < 10; i++ { c <- i } }() for i := 0; i < 10; i++ { fmt.Println(<-c) } } ``` 上面的代码中,主 Goroutine 和子 Goroutine 之间使用 channel 进行通信,子 Goroutine 向 channel 中写入数据,主 Goroutine 从 channel 中读取数据并打印。 2. Mutex 由于 Goroutine 的并发性,多个 Goroutine 可以同时访问共享资源,这可能会导致数据竞争并导致数据不一致或损坏。因此,Go 语言提供了 Mutex(互斥锁)来保护共享资源的访问。 Mutex 可以通过 Lock 和 Unlock 方法进行加锁和解锁: ``` type Counter struct { value int mu sync.Mutex } func (c *Counter) Increment() { c.mu.Lock() defer c.mu.Unlock() c.value++ } func (c *Counter) Get() int { c.mu.Lock() defer c.mu.Unlock() return c.value } ``` 上面的代码中,Counter 类型包含一个值和一个 Mutex,Increment 和 Get 方法都是通过 Mutex 来保护共享资源 value 的访问。 3. WaitGroup 当我们需要等待多个 Goroutine 完成时,可以使用 WaitGroup(等待组)来进行同步。WaitGroup 维护了一个计数器,我们可以使用 Add 方法增加计数器的值,Done 方法减少计数器的值,Wait 方法等待计数器的值为 0。 ``` func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { // Goroutine 代码块 wg.Done() }() } wg.Wait() } ``` 上面的代码中,我们使用 WaitGroup 等待 10 个 Goroutine 完成。 4. Select 当我们需要从多个 channel 中同时接收数据时,可以使用 Select 语句。Select 可以监听多个 channel,并从其中一个非空的 channel 中接收数据。 ``` func main() { c1 := make(chan int) c2 := make(chan int) go func() { for i := 0; i < 10; i++ { c1 <- i time.Sleep(time.Millisecond * 50) } }() go func() { for i := 0; i < 10; i++ { c2 <- i time.Sleep(time.Millisecond * 100) } }() for i := 0; i < 20; i++ { select { case v := <-c1: fmt.Println("c1:", v) case v := <-c2: fmt.Println("c2:", v) } } } ``` 上面的代码中,我们创建了两个 channel c1 和 c2,并在两个 Goroutine 中向其中写入数据,主 Goroutine 中使用 Select 监听两个 channel,并从其中一个非空的 channel 中接收数据并打印。 结语 本文介绍了 Golang 常用的并发模型及其应用案例,包括 Goroutine、Mutex、WaitGroup 和 Select。并发编程是现代应用程序的基础,学习并发编程的知识是非常重要的。