面试题答案
一键面试竞态条件产生的原因
在Go语言并发编程中,竞态条件产生主要是因为多个并发执行的goroutine同时访问和修改共享资源。当多个goroutine对同一共享变量进行读写操作时,如果没有合适的同步机制,操作的执行顺序就无法预测,可能导致数据不一致或其他错误行为。例如,一个goroutine读取共享变量的值,同时另一个goroutine修改该值,最终读取到的值可能并不是预期的,这就产生了竞态条件。
避免竞态条件的方法
- 互斥锁(Mutex):通过互斥锁保护共享资源,同一时间只有一个goroutine可以访问共享资源。
- 读写锁(RWMutex):适用于读多写少的场景,允许多个goroutine同时读共享资源,但写操作需要独占。
- 通道(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。