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。并发编程是现代应用程序的基础,学习并发编程的知识是非常重要的。