MST

星途 面试题库

面试题:Go语言中RWMutex在多线程读写场景下的应用

在Go语言中,假设有一个场景,多个协程会频繁读取一个共享数据结构,同时偶尔会有一个协程对该数据结构进行写入操作。请描述如何使用RWMutex来保证数据的一致性,并给出简单的代码示例。
25.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 使用RWMutex保证数据一致性的原理
    • RWMutex(读写互斥锁)是Go语言标准库中用于读写操作控制的同步原语。
    • 对于读操作,多个协程可以同时进行,因为读操作不会改变数据,所以不会产生数据竞争。RWMutex允许多个读操作并发执行。
    • 对于写操作,为了保证数据一致性,写操作必须是独占的,即当有一个协程进行写操作时,其他任何读或写操作都不能进行。
  2. 代码示例
package main

import (
    "fmt"
    "sync"
)

type Data struct {
    value int
    mu    sync.RWMutex
}

// Read 方法用于读取共享数据
func (d *Data) Read() int {
    d.mu.RLock()
    defer d.mu.RUnlock()
    return d.value
}

// Write 方法用于写入共享数据
func (d *Data) Write(newValue int) {
    d.mu.Lock()
    defer d.mu.Unlock()
    d.value = newValue
}

可以通过以下方式测试上述代码:

func main() {
    var wg sync.WaitGroup
    data := Data{}

    // 模拟多个读协程
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Read value:", data.Read())
        }()
    }

    // 模拟一个写协程
    wg.Add(1)
    go func() {
        defer wg.Done()
        data.Write(42)
        fmt.Println("Write value: 42")
    }()

    wg.Wait()
}

在上述代码中:

  • Data结构体包含一个共享数据value和一个RWMutex实例mu
  • Read方法在读取数据前调用RLock,这允许其他读操作同时进行,读取完成后调用RUnlock
  • Write方法在写入数据前调用Lock,这会阻止其他读或写操作,写入完成后调用Unlock
  • main函数中,启动了多个读协程和一个写协程来模拟实际场景。sync.WaitGroup用于等待所有协程完成。