MST

星途 面试题库

面试题:Go语言并发编程中如何避免竞态条件

在Go语言的并发编程场景下,详细描述竞态条件产生的原因。列举至少三种避免竞态条件的方法,并结合代码示例说明其中一种方法的具体应用。
33.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

竞态条件产生的原因

在Go语言并发编程中,竞态条件产生主要是因为多个并发执行的goroutine同时访问和修改共享资源。当多个goroutine对同一共享变量进行读写操作时,如果没有合适的同步机制,操作的执行顺序就无法预测,可能导致数据不一致或其他错误行为。例如,一个goroutine读取共享变量的值,同时另一个goroutine修改该值,最终读取到的值可能并不是预期的,这就产生了竞态条件。

避免竞态条件的方法

  1. 互斥锁(Mutex):通过互斥锁保护共享资源,同一时间只有一个goroutine可以访问共享资源。
  2. 读写锁(RWMutex):适用于读多写少的场景,允许多个goroutine同时读共享资源,但写操作需要独占。
  3. 通道(Channel):使用通道在goroutine之间传递数据,避免直接共享资源,从而防止竞态条件。

互斥锁应用示例

package main

import (
    "fmt"
    "sync"
)

var (
    counter int
    mu      sync.Mutex
)

func increment(wg *sync.WaitGroup) {
    defer wg.Done()
    mu.Lock()
    counter++
    mu.Unlock()
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go increment(&wg)
    }
    wg.Wait()
    fmt.Println("Final counter value:", counter)
}

在上述代码中,mu 是一个互斥锁。在 increment 函数中,通过 mu.Lock() 锁定互斥锁,这样在同一时间只有一个goroutine可以执行 counter++ 操作,完成操作后通过 mu.Unlock() 解锁,从而避免了竞态条件。最终 counter 的值是预期的1000。