map写入源代码写冲突

在 map 写入的时候,源代码有段如下

if h.flags&hashWriting != 0 {
    throw("concurrent map writes")
}
hash := t.hasher(key, uintptr(h.hash0))

h.flags ^= hashWriting

上面的作用应该是避免写冲突,但是我看着如果两个 goroutine 一起进来,h.flags&hashWriting 并不会把它们拦住,前后脚进入 h.flags ^= hashWriting,最终 h.flags 的 hashWriting 位变成 0 了,也达不到避免写冲突的效果,这么理解是哪里不对?

最佳答案

并发检查:
1.h.flags&hashWriting != 0
h.flags 默认为 0,此时条件判断为 false
若 flags 不为 0,则已有 gorountine 在修改 map,throw ("concurrent map writes")
2. 确认无同时写后更新 flags 值 - h.flags^= hashWriting,此时 flags 改为 4
3. 携入完成时再次检查
h.flags&hashWriting == 0
此时 flags 应仍为 4,说明无其他 gorountine 操作,结果为 false
若 flags 已被重置为 0,则说明发生并发操作,throw ("concurrent map writes")
4. 重置 flags 为 0 h.flags&^= hashWriting

简单的保证不会同时有多个 gorountine 进行数据操作

4年前 评论
讨论数量: 1

并发检查:
1.h.flags&hashWriting != 0
h.flags 默认为 0,此时条件判断为 false
若 flags 不为 0,则已有 gorountine 在修改 map,throw ("concurrent map writes")
2. 确认无同时写后更新 flags 值 - h.flags^= hashWriting,此时 flags 改为 4
3. 携入完成时再次检查
h.flags&hashWriting == 0
此时 flags 应仍为 4,说明无其他 gorountine 操作,结果为 false
若 flags 已被重置为 0,则说明发生并发操作,throw ("concurrent map writes")
4. 重置 flags 为 0 h.flags&^= hashWriting

简单的保证不会同时有多个 gorountine 进行数据操作

4年前 评论