go 最新版的 map 并发读是安全的吗。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golan.org/
Go Playground
Go Projects
Revel Web Framework
SGL
V2EX    Go 编程语言

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

  •  
  •   SGL2 天前 3221 次点击
    只读不写,写的时候加锁,读的时候并发,这个安全吗。
    24 条回复    2025-10-24 14:25:08 +08:00
    SGL
        1
    SGL  
    OP
       2 天前
    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  
       2 天前
    并发读是安全的,但如果你读不加锁,不能保证读的时候没有写,如果读的时候遇到了写,就会 panic
    xdeng
        3
    xdeng  
       2 天前
    标准库封装了个 sync.Map
    Nanosk
        4
    Nanosk  
       2 天前   1
    你发这个是旧的 map 吧,如果是 2 楼说的基本没问题,只有一点不太正确,并发读写并不是 panic ,而是 fatal
    新的 SwissMap 没看过源码 不了解。
    git00ll
        5
    git00ll  
       2 天前
    要用读写锁吧,不然可能读到不一致的数据
    me262
        6
    me262  
       2 天前   1
    https://go.dev/blog/swisstable
    别乱发啊 2 楼,最新都是 swiss table
    ripperdev
        7
    ripperdev  
       2 天前
    sync.Map 针对读多写少有优化,直接用就好了
    oom
        8
    oom  
       2 天前
    不安全,读多写少加读写锁,或者使用原子 sync.Map ,但是取值相对麻烦
    kfpenn
        9
    kfpenn  
       2 天前
    @me262 所以呢?这个说明也没说最新的 map 支持并发啊
    aladdinding
        10
    aladdinding  
       2 天前
    我一般都是并发读,指针替换更新整个 map
    ca2oh4
        11
    ca2oh4  
       2 天前
    sync.Map 太抽象了,连个类型都不给
    ca2oh4
        12
    ca2oh4  
       2 天前
    @ripperdev sync.Map 太抽象了,连个类型都不给
    charlie21
        13
    charlie21  
       2 天前 via Android
    有意思
    ripperdev
        14
    ripperdev  
       2 天前
    @ca2oh4 #12 什么意思?是指 Key 和 Value 都是 any 类型?
    xxx88xxx
        15
    xxx88xxx  
       2 天前 via Android
    我今天问了 GPT 类似的问题,GPT 告诉我最最优的方法是:并发前,将 map 深度拷贝后在使用
    zoharSoul
        16
    zoharSoul  
       1 天前
    不是
    Tidusy
        17
    Tidusy  
       1 天前
    写和读同时触发会 fatal panic 的吧
    bingfengfeifei
        18
    bingfengfeifei  
       1 天前
    写的时候加锁,加的是什么锁?那读的时候用锁吗?
    1. 如果读的时候不用锁,仅仅写的时候用锁,那锁给谁的呢。 这不还可能在写的时候同时读吗。这种情况肯定是不行的。
    2. 如果写的时候锁,读的时候也加读锁,这种是可以的,但是根据你的问法,好像并不是这种全加锁场景。
    strobber16
        19
    strobber16  
       1 天前 via Android
    我还在等 sync/v2
    ca2oh4
        20
    ca2oh4  
       1 天前
    @ripperdev 没错就是万恶的 any
    stephenxiaxy
        21
    stephenxiaxy  
       1 天前
    你们并发 map 不用第三方的吗
    lovelylain
        22
    lovelylain  
       1 天前
    go1.25 版本 sync.Map 内部是范型实现,不知道为什么对外只提供 any 类型的
    carlojie
        23
    carlojie  
       1 天前
    @me262 感谢分享, 这篇文章没有说明支持并发写,只说了 map 空间扩展时 map 迭代的特性
    me262
        24
    me262  
       1 天前
    如果你的 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     2353 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 10:51 PVG 18:51 LAX 03:51 JFK 06:51
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86