MST

星途 面试题库

面试题:Go语言中Mutex如何确保简单切片数据结构的线程安全

假设你有一个Go语言的切片,里面存放整数。请编写代码,利用`Mutex`来确保在多个并发的读写操作下,这个切片数据的完整性和一致性。要求展示如何在读取和写入切片时正确地使用`Mutex`。
46.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
    "sync"
)

type SafeSlice struct {
    data []int
    mu   sync.Mutex
}

func (s *SafeSlice) Append(num int) {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.data = append(s.data, num)
}

func (s *SafeSlice) Read() []int {
    s.mu.Lock()
    defer s.mu.Unlock()
    result := make([]int, len(s.data))
    copy(result, s.data)
    return result
}

func main() {
    safeSlice := SafeSlice{}
    var wg sync.WaitGroup

    // 模拟多个并发写入
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(num int) {
            defer wg.Done()
            safeSlice.Append(num)
        }(i)
    }

    // 等待所有写入完成
    go func() {
        wg.Wait()
        data := safeSlice.Read()
        fmt.Println("Final data:", data)
    }()

    // 防止主线程退出
    select {}
}

在上述代码中:

  1. 定义了一个 SafeSlice 结构体,包含一个存放整数的切片 data 和一个互斥锁 mu
  2. Append 方法用于向切片中追加数据,在操作前加锁,操作完成后解锁,保证写入操作的原子性。
  3. Read 方法用于读取切片数据,同样在操作前加锁,操作完成后解锁。这里通过复制切片内容来返回,避免返回内部切片导致外部直接修改。
  4. main 函数中,模拟了多个并发的写入操作,并在所有写入完成后读取数据并打印。select {} 用于防止主线程过早退出。