MST

星途 面试题库

面试题:Go中Goroutine在Web服务并发处理时如何避免资源竞争

在一个简单的Web服务中,使用Goroutine处理多个请求,每个请求可能会对共享资源进行读写操作。请描述如何使用Go的同步机制(如互斥锁、读写锁等)来避免资源竞争,并给出一个简单的代码示例。
15.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,为避免多个Goroutine对共享资源的读写操作导致资源竞争,可以使用以下同步机制:

  1. 互斥锁(sync.Mutex:适用于读写操作都需要保证原子性的场景,任何时刻只允许一个Goroutine进行读写操作。
  2. 读写锁(sync.RWMutex:适用于读多写少的场景,允许多个Goroutine同时读,但写操作时需要独占资源。

以下是使用读写锁的简单代码示例:

package main

import (
    "fmt"
    "sync"
)

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

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

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

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

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

    wg.Wait()
}

在上述代码中:

  • sync.RWMutex 定义了一个读写锁 rwmu
  • reader 函数使用 rwmu.RLock() 进行读锁定,允许多个Goroutine同时读取数据,读操作完成后使用 rwmu.RUnlock() 解锁。
  • writer 函数使用 rwmu.Lock() 进行写锁定,保证写操作的原子性,写操作完成后使用 rwmu.Unlock() 解锁。
  • main 函数启动了多个读和写的Goroutine,并使用 sync.WaitGroup 等待所有Goroutine完成。