MST

星途 面试题库

面试题:Go函数安全性考量之高级难度:并发安全

假设你正在开发一个多线程环境下使用的Go函数,该函数会对共享的map进行读写操作。请描述如何确保该函数在并发情况下的安全性,并且给出具体实现代码,包括如何使用sync包中的工具来避免数据竞争问题。
42.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

为了确保在多线程环境下对共享 map 进行读写操作的安全性,我们可以使用 sync.RWMutexRWMutex 允许读操作并发执行,但写操作会独占锁,从而避免数据竞争。

以下是具体实现代码:

package main

import (
    "fmt"
    "sync"
)

type SafeMap struct {
    mu sync.RWMutex
    data map[string]interface{}
}

func NewSafeMap() *SafeMap {
    return &SafeMap{
        data: make(map[string]interface{}),
    }
}

func (sm *SafeMap) Get(key string) (interface{}, bool) {
    sm.mu.RLock()
    defer sm.mu.RUnlock()
    value, exists := sm.data[key]
    return value, exists
}

func (sm *SafeMap) Set(key string, value interface{}) {
    sm.mu.Lock()
    defer sm.mu.Unlock()
    sm.data[key] = value
}

func main() {
    safeMap := NewSafeMap()

    var wg sync.WaitGroup
    wg.Add(2)

    go func() {
        defer wg.Done()
        safeMap.Set("key1", "value1")
    }()

    go func() {
        defer wg.Done()
        value, exists := safeMap.Get("key1")
        if exists {
            fmt.Println("Value:", value)
        }
    }()

    wg.Wait()
}

在上述代码中:

  1. 定义了一个 SafeMap 结构体,其中包含一个 sync.RWMutex 和一个 map
  2. NewSafeMap 函数用于初始化 SafeMap
  3. Get 方法使用 RLock 进行读操作,允许多个读操作并发执行。
  4. Set 方法使用 Lock 进行写操作,确保写操作的原子性,避免数据竞争。
  5. main 函数中,通过启动两个 goroutine 来演示并发读写操作的安全性。