Go 语言不支持并发读写 Map,为什么?

2024年 1月 5日 73.7k 0

Go语言的map类型不支持并发读写的主要原因是并发读写会导致数据竞态(data race),这意味着多个 goroutine 可能同时访问并修改同一个 map,从而引发不确定的结果。

在Go语言的设计中,为了防止数据竞态,不同于一些其他语言,map并没有提供内置的锁机制。这样设计的目的是为了鼓励开发者使用更加精细的同步措施,以适应不同的并发场景。

如果你需要在多个 goroutine 中安全地使用 map,可以考虑以下几种方法:

1 加锁: 使用 sync.Mutex 或 sync.RWMutex 来保护对 map 的读写操作。

package main

import (
    "sync"
)

var (
    mu   sync.Mutex
    data = make(map[string]string)
)

func writeToMap(key, value string) {
    mu.Lock()
    defer mu.Unlock()
    data[key] = value
}

func readFromMap(key string) string {
    mu.Lock()
    defer mu.Unlock()
    return data[key]
}

func main() {
    // 使用 writeToMap 和 readFromMap 安全地对 map 进行读写
}

2 使用 sync.Map: 在Go 1.9及以上版本,标准库中提供了 sync.Map 类型,它是一种并发安全的 map 实现。

package main

import (
    "sync"
)

var m sync.Map

func main() {
    // 使用 m.Store() 和 m.Load() 安全地对 map 进行读写
}

sync.Map 提供了一些方法来实现并发安全的读写操作,而无需额外的锁。

图片图片

3 使用通道: 可以通过通道在不同的 goroutine 之间传递消息,避免直接对 map 进行并发访问。

package main

import (
"sync"
)

var (
data = make(map[string]string)
readCh = make(chan readRequest)
writeCh = make(chan writeRequest)
shutdown = make(chan struct{})
wg sync.WaitGroup
)

type readRequest struct {
key string
result chan

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论