V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
YanSeven
V2EX  ›  Go 编程语言

go 最新版的 map 并发读是安全的吗。

  •  
  •   YanSeven · 29 天前 · 3993 次点击
    只读不写,写的时候加锁,读的时候并发,这个安全吗。
    24 条回复    2025-10-24 14:25:08 +08:00
    YanSeven
        1
    YanSeven  
    OP
       29 天前
    Maps are not safe for concurrent use: it’s not defined what happens when you read and write to them simultaneously. If you need to read from and write to a map from concurrently executing goroutines, the accesses must be mediated by some kind of synchronization mechanism. One common way to protect maps is with sync.RWMutex.
    映射结构不适用于并发场景:当同时进行读写操作时,其行为是未定义的。若需要在并发执行的 goroutine 中对映射进行读写操作,必须通过某种同步机制来协调访问。保护映射的常用方式之一是使用 sync.RWMutex 。

    This statement declares a counter variable that is an anonymous struct containing a map and an embedded sync.RWMutex.
    该语句声明了一个 counter 变量,这是一个包含映射和嵌入式 sync.RWMutex 的匿名结构体。

    var counter = struct{
    sync.RWMutex
    m map[string]int
    }{m: make(map[string]int)}
    To read from the counter, take the read lock:
    读取计数器时需获取读锁:

    counter.RLock()
    n := counter.m["some_key"]
    counter.RUnlock()
    fmt.Println("some_key:", n)
    To write to the counter, take the write lock:
    写入计数器时需获取写锁:

    counter.Lock()
    counter.m["some_key"]++
    counter.Unlock()

    来源: https://go.dev/blog/maps?utm_source=chatgpt.com
    kfpenn
        2
    kfpenn  
       29 天前
    并发读是安全的,但如果你读不加锁,不能保证读的时候没有写,如果读的时候遇到了写,就会 panic
    xdeng
        3
    xdeng  
       29 天前
    标准库封装了个 sync.Map
    Nanosk
        4
    Nanosk  
       29 天前   ❤️ 1
    你发这个是旧的 map 吧,如果是 2 楼说的基本没问题,只有一点不太正确,并发读写并不是 panic ,而是 fatal
    新的 SwissMap 没看过源码 不了解。
    git00ll
        5
    git00ll  
       29 天前
    要用读写锁吧,不然可能读到不一致的数据
    me262
        6
    me262  
       28 天前   ❤️ 1
    https://go.dev/blog/swisstable
    别乱发啊 2 楼,最新都是 swiss table
    ripperdev
        7
    ripperdev  
       28 天前
    sync.Map 针对读多写少有优化,直接用就好了
    oom
        8
    oom  
       28 天前
    不安全,读多写少加读写锁,或者使用原子 sync.Map ,但是取值相对麻烦
    kfpenn
        9
    kfpenn  
       28 天前
    @me262 所以呢?这个说明也没说最新的 map 支持并发啊
    aladdinding
        10
    aladdinding  
       28 天前
    我一般都是并发读,指针替换更新整个 map
    ca2oh4
        11
    ca2oh4  
       28 天前
    sync.Map 太抽象了,连个类型都不给
    ca2oh4
        12
    ca2oh4  
       28 天前
    @ripperdev sync.Map 太抽象了,连个类型都不给
    charlie21
        13
    charlie21  
       28 天前 via Android
    有意思
    ripperdev
        14
    ripperdev  
       28 天前
    @ca2oh4 #12 什么意思?是指 Key 和 Value 都是 any 类型?
    xxx88xxx
        15
    xxx88xxx  
       28 天前 via Android
    我今天问了 GPT 类似的问题,GPT 告诉我最最优的方法是:并发前,将 map 深度拷贝后在使用
    zoharSoul
        16
    zoharSoul  
       28 天前
    不是
    Tidusy
        17
    Tidusy  
       28 天前
    写和读同时触发会 fatal panic 的吧
    bingfengfeifei
        18
    bingfengfeifei  
       28 天前
    写的时候加锁,加的是什么锁?那读的时候用锁吗?
    1. 如果读的时候不用锁,仅仅写的时候用锁,那锁给谁的呢。 这不还可能在写的时候同时读吗。这种情况肯定是不行的。
    2. 如果写的时候锁,读的时候也加读锁,这种是可以的,但是根据你的问法,好像并不是这种全加锁场景。
    strobber16
        19
    strobber16  
       28 天前 via Android
    我还在等 sync/v2
    ca2oh4
        20
    ca2oh4  
       28 天前
    @ripperdev 没错就是万恶的 any
    stephenxiaxy
        21
    stephenxiaxy  
       28 天前
    你们并发 map 不用第三方的吗
    lovelylain
        22
    lovelylain  
       27 天前
    go1.25 版本 sync.Map 内部是范型实现,不知道为什么对外只提供 any 类型的
    carlojie
        23
    carlojie  
       27 天前
    @me262 感谢分享, 这篇文章没有说明支持并发写,只说了 map 空间扩展时 map 迭代的特性
    me262
        24
    me262  
       27 天前
    如果你的 map 是初始化写一下,后续都是读那完全可以放心
    并发读写 map 的场景一直都是不支持的,不然不会有 sync.map 和 github.com/orcaman/concurrent-map
    map 实现 https://github.com/golang/go/tree/master/src/internal/runtime/maps 里面可以搜 Concurrent 看看
    我的答案也是和大家一样 sync.map 或 github.com/orcaman/concurrent-map

    @carlojie
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   5328 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 03:16 · PVG 11:16 · LAX 19:16 · JFK 22:16
    ♥ Do have faith in what you're doing.