MST

星途 面试题库

面试题:Go语言Goroutine并发模式下的资源竞争问题及解决

假设你有一个共享变量在多个Goroutine中读写,描述可能出现的资源竞争问题,并说明如何使用`sync`包中的工具(如`sync.Mutex`、`sync.RWMutex`等)来解决该问题。请给出具体的代码示例,代码要实现多个Goroutine对共享变量的读写操作。
37.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

资源竞争问题

当多个Goroutine同时读写共享变量时,可能会出现资源竞争问题。例如,一个Goroutine正在读取共享变量的值,而另一个Goroutine同时在修改该变量的值,这可能导致读取到的值是不一致或不正确的。

使用sync.Mutex解决资源竞争问题

sync.Mutex是一种互斥锁,用于保证在同一时间只有一个Goroutine可以访问共享资源。以下是使用sync.Mutex实现多个Goroutine对共享变量读写操作的代码示例:

package main

import (
    "fmt"
    "sync"
)

var (
    sharedVariable int
    mu             sync.Mutex
)

func write(wg *sync.WaitGroup) {
    defer wg.Done()
    mu.Lock()
    sharedVariable++
    mu.Unlock()
}

func read(wg *sync.WaitGroup) {
    defer wg.Done()
    mu.Lock()
    fmt.Println("Read value:", sharedVariable)
    mu.Unlock()
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go write(&wg)
    }
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go read(&wg)
    }
    wg.Wait()
}

使用sync.RWMutex解决资源竞争问题

sync.RWMutex是读写锁,允许多个Goroutine同时读取共享资源,但只允许一个Goroutine进行写操作。以下是使用sync.RWMutex实现多个Goroutine对共享变量读写操作的代码示例:

package main

import (
    "fmt"
    "sync"
)

var (
    sharedVariable int
    rwmu           sync.RWMutex
)

func write(wg *sync.WaitGroup) {
    defer wg.Done()
    rwmu.Lock()
    sharedVariable++
    rwmu.Unlock()
}

func read(wg *sync.WaitGroup) {
    defer wg.Done()
    rwmu.RLock()
    fmt.Println("Read value:", sharedVariable)
    rwmu.RUnlock()
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go write(&wg)
    }
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go read(&wg)
    }
    wg.Wait()
}