匠心精神 - 良心品质腾讯认可的专业机构-IT人的高薪实战学院

咨询电话:4000806560

Golang 常用的并发模型及应用案例

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