MST

星途 面试题库

面试题:Go defer与并发资源管理及异常处理

在一个高并发的Go程序中,涉及多个goroutine对共享资源的操作,并且使用defer来管理资源。如何设计机制确保在并发场景下资源的安全访问和正确释放,同时处理可能出现的各种异常情况?请详细阐述设计思路并给出关键代码片段。
39.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 互斥锁(Mutex):为共享资源加锁,确保同一时间只有一个goroutine能访问共享资源,从而保证资源的安全访问。
  2. 读写锁(RWMutex):如果读操作远多于写操作,可以使用读写锁。多个goroutine可以同时进行读操作,但写操作时会独占资源,防止其他读或写操作。
  3. defer与锁的配合:在函数开始时加锁,使用defer在函数结束时解锁,确保锁能正确释放,即使函数中出现异常。
  4. 错误处理:在资源操作过程中,对可能出现的错误进行及时处理,避免错误传播导致资源泄漏或程序崩溃。

关键代码片段

package main

import (
    "fmt"
    "sync"
)

// 定义共享资源
type SharedResource struct {
    data int
    mu   sync.Mutex
}

// 写操作
func (sr *SharedResource) writeData(newData int, wg *sync.WaitGroup) {
    defer wg.Done()
    sr.mu.Lock()
    defer sr.mu.Unlock()
    // 模拟可能出现的错误操作
    if newData < 0 {
        fmt.Println("错误:数据不能为负数")
        return
    }
    sr.data = newData
    fmt.Printf("写入数据: %d\n", sr.data)
}

// 读操作
func (sr *SharedResource) readData(wg *sync.WaitGroup) {
    defer wg.Done()
    sr.mu.RLock()
    defer sr.mu.RUnlock()
    fmt.Printf("读取数据: %d\n", sr.data)
}

func main() {
    var wg sync.WaitGroup
    sharedResource := SharedResource{}

    // 模拟多个写操作
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go sharedResource.writeData(i, &wg)
    }

    // 模拟多个读操作
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go sharedResource.readData(&wg)
    }

    wg.Wait()
}

在上述代码中:

  1. SharedResource 结构体包含一个共享数据 data 和一个互斥锁 mu
  2. writeData 方法使用 mu.Lock()defer mu.Unlock() 来确保写操作的线程安全,并处理了可能的错误情况。
  3. readData 方法使用 mu.RLock()defer mu.RUnlock() 来确保读操作的线程安全。
  4. main 函数中,通过 sync.WaitGroup 来等待所有goroutine完成,模拟了高并发场景下的资源访问。