当前位置: 首页 > news >正文

台州企业网站模板建站上海工业设计公司

台州企业网站模板建站,上海工业设计公司,热搜词排行榜关键词,python网站开发优缺点Sync.Map 原理 通过 read 和 dirty 两个字段实现数据的读写分离,读的数据存在只读字段 read 上,将最新写入的数据存在 dirty 字段上。读取时会先查询 read,不存在再查询 dirty,写入时则只写入 dirty。读取 read 并不需要加锁&am…

Sync.Map

原理

  • 通过 read 和 dirty 两个字段实现数据的读写分离,读的数据存在只读字段 read 上,将最新写入的数据存在 dirty 字段上。
  • 读取时会先查询 read,不存在再查询 dirty,写入时则只写入 dirty。
  • 读取 read 并不需要加锁,而读或写 dirty 则需要加锁。
  • misses 字段来统计 read 被穿透的次数(被穿透指需要读 dirty 的情况),超过一定次数则将 dirty 数据更新到 read 中(触发条件:misses=len(dirty))。

优缺点

  • 优点:通过读写分离,降低锁时间来提高效率。
  • 缺点:不适用于大量写的场景,这样会导致 read map 读不到数据而进一步加锁读取,同时dirty map也会一直晋升为read map,整体性能较差,甚至没有单纯的 map+metux 高。
  • 适用场景:读多写少的场景。

Sync.Map 数据结构

type Map struct {mu Mutexread atomic.Value // readOnly// 包含需要加锁才能访问的元素// 包括所有在read字段中但未被expunged(删除)的元素以及新加的元素dirty map[any]*entry// 记录从read中读取miss的次数,一旦miss数和dirty长度一样了,就会把dirty提升为read    misses int
}// readOnly is an immutable struct stored atomically in the Map.read field.
type readOnly struct {m       map[any]*entryamended bool // true if the dirty map contains some key not in m.
}// expunged is an arbitrary pointer that marks entries which have been deleted
// from the dirty map.
var expunged = unsafe.Pointer(new(any))// An entry is a slot in the map corresponding to a particular key.
type entry struct {p unsafe.Pointer // *interface{}
}

Sync.Map 操作

Store
// Store sets the value for a key.
func (m *Map) Store(key, value any) {// 判断 read 有没有包含这个 key,有则 cas 更新read, _ := m.read.Load().(readOnly)if e, ok := read.m[key]; ok && e.tryStore(&value) {return}// read 没有,需要加锁访问 dirtym.mu.Lock()read, _ = m.read.Load().(readOnly)// 双重检查,在查一下 read 里面有没有(包含标记删除的)if e, ok := read.m[key]; ok {// 之前被标记为删除,重新加入 dirtyif e.unexpungeLocked() {// The entry was previously expunged, which implies that there is a// non-nil dirty map and this entry is not in it.m.dirty[key] = e}e.storeLocked(&value)} else if e, ok := m.dirty[key]; ok {e.storeLocked(&value)} else {if !read.amended {// We're adding the first new key to the dirty map.// Make sure it is allocated and mark the read-only map as incomplete.// 创建一个新的 dirty,遍历 read,将没有标记删除的加入m.dirtyLocked()m.read.Store(readOnly{m: read.m, amended: true})}m.dirty[key] = newEntry(value)}m.mu.Unlock()
}func (m *Map) dirtyLocked() {if m.dirty != nil {return}read, _ := m.read.Load().(readOnly)m.dirty = make(map[any]*entry, len(read.m))for k, e := range read.m {if !e.tryExpungeLocked() {m.dirty[k] = e}}
}

Store 是 新增/修改 操作:

  1. read 里面有,直接 cas 更新。
  2. read 没有,加锁。
  3. 再次检查 read,有已经标记删除的,重用,并更新 value。
  4. dirty 有,直接更新。
  5. dirty 没有,新增一个。如果 dirty 为 nil,创建一个 dirty,遍历 read 将元素加入 dirty。
Load
// Load returns the value stored in the map for a key, or nil if no
// value is present.
// The ok result indicates whether value was found in the map.
func (m *Map) Load(key any) (value any, ok bool) {// 先从 read 获取read, _ := m.read.Load().(readOnly)e, ok := read.m[key]// dirty 中有包含 read 中没有的元素if !ok && read.amended {// 加锁,双检查 read,read 中没有,从 dirty 中获取m.mu.Lock()// Avoid reporting a spurious miss if m.dirty got promoted while we were// blocked on m.mu. (If further loads of the same key will not miss, it's// not worth copying the dirty map for this key.)read, _ = m.read.Load().(readOnly)e, ok = read.m[key]if !ok && read.amended {e, ok = m.dirty[key]// Regardless of whether the entry was present, record a miss: this key// will take the slow path until the dirty map is promoted to the read// map.// miss++m.missLocked()}m.mu.Unlock()}if !ok {return nil, false}return e.load()
}func (m *Map) missLocked() {m.misses++if m.misses < len(m.dirty) {return}// dirty 提升为 readm.read.Store(readOnly{m: m.dirty})// dirty 置为 nilm.dirty = nilm.misses = 0
}

Load 是 读取 操作:

  1. 从 read 中获取,有则直接返回。
  2. read 中没有,加锁
    • 双检查 read, read 有,赋值。
    • read 没有,从 dirty 中获取,不管 dirty 中有没有,miss++
      miss == len(dirty),dirty 提升为 read 字段,清空 dirty。
Delete
// Delete deletes the value for a key.
func (m *Map) Delete(key any) {m.LoadAndDelete(key)
}// LoadAndDelete deletes the value for a key, returning the previous value if any.
// The loaded result reports whether the key was present.
func (m *Map) LoadAndDelete(key any) (value any, loaded bool) {// 从 read 中获取read, _ := m.read.Load().(readOnly)e, ok := read.m[key]if !ok && read.amended {// 加锁,双重检查 readm.mu.Lock()read, _ = m.read.Load().(readOnly)e, ok = read.m[key]if !ok && read.amended {// read 没有,dirty 有,则直接删除 dirty 的keye, ok = m.dirty[key]delete(m.dirty, key)// Regardless of whether the entry was present, record a miss: this key// will take the slow path until the dirty map is promoted to the read// map.m.missLocked()}m.mu.Unlock()}if ok {// 延迟删除:read 的 entry 标记为删除,设置为 nilreturn e.delete()}return nil, false
}func (e *entry) delete() (value any, ok bool) {for {p := atomic.LoadPointer(&e.p)if p == nil || p == expunged {return nil, false}if atomic.CompareAndSwapPointer(&e.p, p, nil) {return *(*any)(p), true}}
}

Delete 是 删除 操作:

  1. 从 read 中获取,有则赋值。
  2. read 没有,加锁
    • 双重检查 read,有则赋值。
    • read 没有,dirty 有,删除 dirty 中的值,给 entry 赋值,miss++。
  3. 延迟删除:read 的 entry 标记为删除,设置为 nil。
http://www.yayakq.cn/news/227229/

相关文章:

  • 帮人做网站一个多少钱免费微信小程序制作
  • 网站设计集团网站规划建设心得与体会
  • 网站数据分析怎么做什么叫网站收录
  • 做商品条形码的网站上海徐汇网站建设
  • 广州制作企业网站学生个人网页制作成品代码
  • 作业提交免费网站网站建设方案包括
  • 网站内存不足营销网名
  • swf格式网站链接怎样做短剧cps分销平台官网
  • 做购物网站收费标准ps做网站边框
  • 哪个网站建设公司好家装设计师需要考证吗
  • 厦门网站建设服务网站搭建开发
  • 网站展示 包括什么ppt做的模板下载网站有哪些
  • 类似qq空间的网站淄博网站制作多样定制
  • 前端和网站部署做网站的12建网站
  • wordpress 洛神的主题北京seo网站
  • 品牌网站建设h合肥黑龙江建设部网站
  • 三点水网站建设合同网络营销推广方法的综合运用
  • 专业做淘宝网站企业级网站开发与部署
  • 有关建设网站的英语文献深圳特区报
  • 电子商务网站建设与推广营销助手下载app下载
  • 莆田外贸专业建站网站建设收费标准流程
  • 梅州建站规划企业建设网站注意点
  • vue网站开发html做的旅游网站
  • 受欢迎的网站建设邵阳建设网站的公司
  • 网站建设哪些网站可以手游充值代理平台
  • 企业信息公开网站手机网站菜单设计
  • 做问卷调查的网站有哪些内容什么是品牌网站
  • wordpress固定链接设置.html360优化大师下载官网
  • 中山森斯网站建设公司建设项目环境登记表辽宁省网站
  • 烟台 网站设计都江堰网站建设培训学校