MST

星途 面试题库

面试题:Go语言中sync包的互斥锁使用场景

请描述在Go语言中,sync包中的互斥锁(Mutex)通常在哪些场景下使用?请举例说明,并阐述使用互斥锁时需要注意的事项。
43.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

1. 适用场景

  • 共享资源访问控制:当多个goroutine需要访问共享资源(如全局变量、共享数据结构等),以避免数据竞争时使用。例如,多个goroutine同时对一个全局计数器进行增减操作。
  • 临界区保护:对一段需要独占执行的代码区域(临界区)进行保护,确保同一时间只有一个goroutine能执行该区域代码。

2. 示例

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 < 10; i++ {
        wg.Add(1)
        go increment(&wg)
    }
    wg.Wait()
    fmt.Println("Final counter value:", counter)
}

在上述代码中,多个goroutine同时调用increment函数对counter进行增加操作,通过互斥锁mu确保每次只有一个goroutine能修改counter,避免数据竞争。

3. 注意事项

  • 正确的加锁解锁配对:必须确保在临界区代码前后正确调用LockUnlock方法,避免死锁。例如,不要在Lock之后的代码逻辑中提前返回而没有调用Unlock
  • 避免嵌套加锁:尽量避免在持有一个互斥锁的情况下再去获取另一个互斥锁,否则可能导致死锁。如果确实需要,要确保加锁顺序的一致性。
  • 性能问题:虽然互斥锁能保证数据安全,但频繁的加锁解锁操作会带来性能开销,因此要尽量缩小临界区代码范围,减少加锁时间。