MST

星途 面试题库

面试题:Go Goroutine的资源管理与同步

假设有多个Goroutine需要访问共享资源,例如一个共享的计数器。请描述如何使用Go语言中的同步原语(如Mutex、WaitGroup等)来确保数据的一致性和线程安全。同时,编写代码实现多个Goroutine对共享计数器进行累加操作,每个Goroutine累加100次,最后输出正确的累加结果。
36.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 使用同步原语确保数据一致性和线程安全的原理
    • Mutex(互斥锁):用于保护共享资源,在同一时间只允许一个Goroutine访问共享资源。当一个Goroutine获取了Mutex锁,其他Goroutine必须等待锁被释放才能访问共享资源,从而避免数据竞争。
    • WaitGroup:用于等待一组Goroutine完成。它内部维护一个计数器,通过Add方法增加计数器的值,通过Done方法减少计数器的值,Wait方法会阻塞直到计数器的值变为0。
  2. 代码实现
package main

import (
    "fmt"
    "sync"
)

func main() {
    var counter int
    var mu sync.Mutex
    var wg sync.WaitGroup

    numGoroutines := 5
    wg.Add(numGoroutines)

    for i := 0; i < numGoroutines; i++ {
        go func() {
            defer wg.Done()
            for j := 0; j < 100; j++ {
                mu.Lock()
                counter++
                mu.Unlock()
            }
        }()
    }

    wg.Wait()
    fmt.Println("Final counter value:", counter)
}

在上述代码中:

  • 定义了一个共享的计数器counter
  • 使用sync.Mutex来保护counter的访问,在每次对counter进行累加操作前,通过mu.Lock()获取锁,操作完成后通过mu.Unlock()释放锁。
  • 使用sync.WaitGroup来等待所有Goroutine完成累加操作。wg.Add(numGoroutines)设置需要等待的Goroutine数量,每个Goroutine在完成任务后调用wg.Done()wg.Wait()会阻塞主线程直到所有Goroutine都调用了wg.Done()。最后输出正确的累加结果,理论上counter的值应该是numGoroutines * 100,即500