MST

星途 面试题库

面试题:Go语言中读写锁在Goroutine并发场景下的应用

在Go语言中,读写锁(sync.RWMutex)适用于读多写少的场景。请阐述读写锁的工作原理,并编写一段代码,展示在多个Goroutine并发读写共享数据时,如何使用读写锁保证数据的一致性和并发安全。
24.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

读写锁工作原理

  1. 读锁(RLock):当一个Goroutine获取读锁时,其他Goroutine也可以同时获取读锁。这是因为读操作不会修改共享数据,多个读操作同时进行不会产生数据不一致问题。
  2. 写锁(Lock):当一个Goroutine获取写锁时,其他Goroutine无论是读锁还是写锁都无法获取,直到写锁被释放。这是为了保证在写操作时,共享数据不会被其他读写操作干扰,确保数据一致性。

代码示例

package main

import (
    "fmt"
    "sync"
)

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

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

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

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

在上述代码中:

  1. data 是共享数据。
  2. rwmu 是读写锁实例。
  3. reader 函数使用 rwmu.RLock() 获取读锁,多个 reader 可以同时运行。
  4. writer 函数使用 rwmu.Lock() 获取写锁,在写操作时会阻止其他读写操作。
  5. main 函数中启动多个读写Goroutine,sync.WaitGroup 用于等待所有Goroutine完成。