MST

星途 面试题库

面试题:Go中WaitGroup如何实现并发安全保障

请阐述在Go语言里,WaitGroup是怎样确保并发环境下数据安全以及操作同步的?并通过一个简单示例代码说明其基本使用方式。
17.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

WaitGroup确保并发环境下数据安全及操作同步的原理

  1. 计数机制:WaitGroup内部维护一个计数器。通过Add方法增加计数器的值,通常在启动新的并发任务前调用,用于告知WaitGroup有多少个任务需要等待完成。当并发任务完成时,使用Done方法,它实际上是对计数器减1。
  2. 阻塞等待:主线程或其他需要等待所有并发任务完成的地方调用Wait方法,该方法会阻塞当前 goroutine,直到计数器的值变为0。这就确保了在所有任务完成之前,相关的后续操作不会提前执行,从而实现了操作同步。
  3. 数据安全:由于WaitGroup本身并不直接处理数据,而是用于协调 goroutine 的执行顺序,它间接保证了数据安全。通过确保所有涉及数据处理的 goroutine 完成后再进行其他操作,避免了数据竞争等问题。例如在多个 goroutine 对共享数据进行写入操作时,只有当所有写入操作完成后,读取该数据的操作才能进行,防止读到未完成修改的数据。

示例代码

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    // 设置计数器为3,表示有3个任务
    wg.Add(3)

    // 启动第一个goroutine
    go func() {
        defer wg.Done()
        fmt.Println("Goroutine 1 is running")
    }()

    // 启动第二个goroutine
    go func() {
        defer wg.Done()
        fmt.Println("Goroutine 2 is running")
    }()

    // 启动第三个goroutine
    go func() {
        defer wg.Done()
        fmt.Println("Goroutine 3 is running")
    }()

    // 等待所有goroutine完成
    wg.Wait()
    fmt.Println("All goroutines have finished")
}

在上述代码中,通过wg.Add(3)设置了等待组的计数器为3,代表有3个并发任务。每个 goroutine 在完成时调用wg.Done()使计数器减1。wg.Wait()会阻塞主线程,直到计数器变为0,即所有3个 goroutine 都执行完wg.Done(),此时才会打印出All goroutines have finished