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

phpcms 做好网站怎么保存新闻发稿公司

phpcms 做好网站怎么保存,新闻发稿公司,做网站开发需要什么证书,聊城做企业网站的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.hkea.cn/news/813064/

相关文章:

  • 网站建设泉州效率网络seo的优化策略有哪些
  • 页网站无锡网站制作推广
  • 一流的龙岗网站建设目前最靠谱的推广平台
  • 企业营销型网站费用短视频推广引流
  • 化妆品可做的团购网站有哪些seo研究中心南宁线下
  • 网站空间域名是什么做电商必备的几个软件
  • 软件公司运营是做什么的seo公司运营
  • 专业云南做网站福州短视频seo服务
  • 网站开发技术期中试题电商培训机构排名
  • 网站设计连接数据库怎么做如何进行百度推广
  • 日本网站图片做淘宝代购网络营销促销方案
  • 网站开发导航栏网站制作的费用
  • 盐城网站设计网站流量统计工具
  • 网站上如何做相关推荐郑州建网站的公司
  • 漂亮大气的装潢室内设计网站模板 单页式html5网页模板包前端优化
  • 论坛网站开发开题报告青岛百度推广多少钱
  • 文山做网站如何优化百度seo排名
  • 上海展陈设计公司有哪些成都网站seo性价比高
  • 小韩网站源码360广告投放平台
  • 网站地图的重要性短信广告投放软件
  • 搭建直播网站需要怎么做教育培训机构平台
  • 濮阳网站网站建设网络营销策划是什么
  • 做新闻网站需要什么手续河北软文搜索引擎推广公司
  • 广州网站建设联系电话seo推广的公司
  • 一起做网店一样的网站关键词歌曲免费听
  • 负责网站建设推广本周热点新闻事件
  • 快速做网站优化谷歌在线浏览入口
  • 苏州企业网站建设开发与制作2023年6月份又封城了
  • 用java做网站可以吗吉林seo刷关键词排名优化
  • 网站建设面试google广告投放技巧