golang sync.Map实现原理

sync.Map 的实现原理可概括为: 通过 read 和 dirty 两个字段将读写分离,读的数据存在只读字段 read 上,将最新写入的数据则存在 dirty 字段上 读取时会先查询 read,不存在再查询 dirty,写入时则只写入 dirty,当达到同步的条件时,将dirty的数据同步到read中。

type Map struct {
    mu Mutex // 操作dirty时候上的锁
    read atomic.Value // readOnly
    dirty map[interface{}]*entry
    misses int // 从dirty读加1,超过一定次数dirty同步到read
}

// readOnly is an immutable struct stored atomically in the Map.read field.
type readOnly struct {
    m       map[interface{}]*entry
    amended bool // 如果dirty中有的read中没有的,标记为true
}

// expunged is an arbitrary pointer that marks entries which have been deleted
// from the dirty map.
var expunged = unsafe.Pointer(new(interface{}))

type entry struct {
    // If p == nil, the entry has been deleted and m.dirty == nil.
    // If p == expunged, the entry has been deleted, m.dirty != nil, and the entry
    // is missing from m.dirty.

    p unsafe.Pointer // *interface{}
}

优点

sync.Map 的主要思想就是读写分离,空间换时间。

看看 sync.map 优点:

  • 空间换时间:通过冗余的两个数据结构(read、dirty),实现加锁对性能的影响。
  • 使用只读数据(read),避免读写冲突。
  • 动态调整,miss次数多了之后,将dirty数据迁移到read中。
  • double-checking。
  • 延迟删除。 删除一个键值只是打标记,只有在迁移dirty数据的时候才清理删除的数据。
  • 优先从read读取、更新、删除,因为对read的读取不需要锁。
kafka高并发基于什么实现
golang channel操作情况
标签:

发表我的评论

电子邮件地址不会被公开。 必填项已用*标注

62 + 60 =

ajax-loader