MST
星途 面试题库

面试题:Go中使用读写锁优化并发读多写少场景的资源竞争

在一个应用场景中,有大量的goroutine会频繁读取一个共享的配置信息(如数据库连接字符串等),但偶尔会有goroutine去更新这个配置信息。请利用Go语言的读写锁(`sync.RWMutex`)来优化此场景,避免资源竞争,写出关键代码片段并解释其原理。
47.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
    "sync"
    "time"
)

var (
    config    string
    rwMutex   sync.RWMutex
)

func readConfig(id int) {
    for {
        rwMutex.RLock()
        fmt.Printf("Goroutine %d reads config: %s\n", id, config)
        rwMutex.RUnlock()
        time.Sleep(time.Millisecond * 100)
    }
}

func writeConfig(id int, newConfig string) {
    for {
        rwMutex.Lock()
        config = newConfig
        fmt.Printf("Goroutine %d updates config to: %s\n", id, config)
        rwMutex.Unlock()
        time.Sleep(time.Second)
    }
}

原理解释

  1. sync.RWMutex:Go语言提供的读写锁,允许并发读操作,但写操作需要独占锁。
  2. 读操作:在readConfig函数中,使用rwMutex.RLock()获取读锁,允许多个读操作同时进行,因为读操作不会改变数据,所以不会引发资源竞争。读取完成后使用rwMutex.RUnlock()释放读锁。
  3. 写操作:在writeConfig函数中,使用rwMutex.Lock()获取写锁,写锁是独占的,此时其他读写操作都无法进行,确保在更新配置信息时不会有其他读或写操作干扰,更新完成后使用rwMutex.Unlock()释放写锁。通过这种方式,读写锁有效地避免了共享配置信息在读写过程中的资源竞争问题。