MST

星途 面试题库

面试题:Go语言中Mutex锁在读写场景的应用

在Go语言中,如果有一个场景,多个协程需要同时读取数据,但只有一个协程会进行写操作,如何合理使用Mutex锁来保证数据一致性?请写出简单示例代码并解释原理。
15.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

原理

在这种场景下,读操作可以并发执行,因为读操作不会修改数据,不会产生数据竞争。而写操作会改变数据,所以需要在写操作时加锁,防止其他协程在写操作进行时读取或写入数据,保证数据一致性。对于读操作,可以使用读锁(RWMutex 中的读锁),允许多个读操作同时进行;写操作使用写锁,保证写操作的原子性,同一时间只有一个写操作能执行。

示例代码

package main

import (
    "fmt"
    "sync"
)

var (
    data  int
    rwmu  sync.RWMutex
    wg    sync.WaitGroup
)

func read(id int) {
    defer wg.Done()
    rwmu.RLock()
    defer rwmu.RUnlock()
    fmt.Printf("Reader %d reads data: %d\n", id, data)
}

func write(id int) {
    defer wg.Done()
    rwmu.Lock()
    defer rwmu.Unlock()
    data++
    fmt.Printf("Writer %d writes data: %d\n", id, data)
}

func main() {
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go read(i)
    }

    for i := 0; i < 1; i++ {
        wg.Add(1)
        go write(i)
    }

    wg.Wait()
}

在上述代码中:

  1. sync.RWMutex 用于读写锁。
  2. read 函数使用 rwmu.RLock() 获取读锁,允许多个读操作同时进行,完成后使用 rwmu.RUnlock() 释放读锁。
  3. write 函数使用 rwmu.Lock() 获取写锁,保证同一时间只有一个写操作能执行,完成后使用 rwmu.Unlock() 释放写锁。
  4. main 函数中启动多个读协程和一个写协程,通过 sync.WaitGroup 等待所有协程完成。