LockFree 之 AtomicHashMap

news/2024/11/28 22:21:48/文章来源:https://www.cnblogs.com/chenny7/p/16801251.html

AtomicHashMap

 

github 仓库:https://github.com/facebook/folly/tree/main/folly

文档:https://github.com/facebook/folly/blob/main/folly/docs/AtomicHashMap.md

 

本文只简单介绍下 folly库的 AtomicHashMap 实现思想,详细设计可以直接看源码。

 

AtomicHashMap  是基于 AtomicHasArray 实现的。

本质上,AtomicHashArray就是一个静态数组,通过CAS操作实现并发插入、删除操作。关键在于如何封装使得对元素操作原子化。

AtomicHashArray,为 key 提供了三个标志元素 empty_key、locked_key、erased_key;

  • 初始化,所有元素的 key = empty_key;
    • AtomicHashArray 采用固定长度的设计,不支持扩容;
  • 插入 key = target 的元素,
    • 通过 CAS(key, empty_key, locked_key) 方式锁定一个空元素;
    • 更新完之后,key 的状态从 locked_key 变成新的 target 值;
    • key 发生冲突时,使用开放寻址继续探测数组中的下一个位置是否可用(没有使用挂链表的方式);
    • 如果数组满了,直接返回失败;
  • 更新,
    • 如果当前元素的 key 已经等于 target,说明 key 已经存在;
  • 删除 key = target 的元素,
    • 通过 CAS(key, target, erased_key) 方式锁定要删除的元素;
    • 此时 key = erased_key(被标记已删除),但 value 还在,防止其它线程仍在使用 value;
    • 那什么时候可以释放 value 呢,并同时把 key 从 erased_key 改成 empty_key(key 可以被复用)?一种方式是提供一个 erase() 方法由使用方决定何时释放,另一种方式是使用类似风险指针的方式来延迟 GC;

插入的代码(简化后的流程),

insertInternal(LookupKeyT key_in, ArgTs&&... vCtorArgs) {size_t idx = keyToAnchorIdx<LookupKeyT, LookupHashFcn>(key_in);for (;;) {value_type* cell = &cells_[idx];KeyT currentKey = acquireLoadKey(*cell);if (currentKey == kEmptyKey_) {// 可以插入新键// CAS 修改成功if (compare_exchange_strong(currentKey, kEmptyKey_, kLockedKey_)) {return SimpleRetT(idx, true);}} if (currentKey == kLockedKey_) {// 等待解锁detail::atomic_hash_spin_wait([&] { return currentKey != kLockedKey_; });} if (LookupEqualFcn()(currentKey, key_in)) {// 插入的 key 已存在,不会覆盖return SimpleRetT(idx, false);} else if (currentKey == kLockedKey_ || currentKey == kEmptyKey_) {// 重试continue;}// 继续探测下一个位置idx = ProbeFcn()(idx, numProbes, capacity_);}
}

 

 

 

AtomicHashArray 类包含 3 个原子类型:

std::atomic<int64_t> isFull_;        // Used by insertInternal

std::atomic<int64_t> numErases_;      // Successful key erases

std::atomic<KeyT> *cellkeyptr_;      // cell中key的指针。

 

 

AtomicHashMap 类

std::atomic<SubMap*>subMaps_[kNumSubMaps_];  // 指向AtomicHashArray, kNumSubMaps_ = 16
std::atomic<uint32_t> numMapsAllocated_;    // 记录AtomicHashArray数目

 

AtomicHashMap 包含一个子映射数组(subMaps_),

  • 插入 key,
    • 先计算使用哪个子映射,然后计算在该子映射的下标,如果该位置可用,直接插入,如果不可用,换一个子映射继续尝试插入;
    • 如果所有子映射都不可用,判断当前子映射个数是否超过上限,没有的话,会尝试新建一个子映射;
    • 如果子映射个数达到上限,插入失败;
  • 查找,需要遍历所有子映射;

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/843117.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jquery数字格式化分隔符插件

jquery-number-divider是一款jquery数字格式化分隔符插件。该数字格式化插件可以按指定格式对大数字进行分隔,可以指定分隔符,是一款简单实用的数字格式化插件。在线演示 下载 安装 可以通过bower来安装number-divider.js数字格式化插件。bower install number-divider …

MySQL底层概述—2.InnoDB磁盘结构

大纲 1.InnoDB磁盘结构 2.表空间(Tablespaces) 3.数据字典(Data Dictionary) 4.双写缓冲区(Double Write Buffer Files) 5.重做日志(redo log) 6.撤销日志(undo log) 7.二进制日志(binlog) 8.新版本结构演变1.InnoDB磁盘结构 (1)Tablespaces (2)Double Write Buffer (3)redo lo…

36. MySQL补充知识点

1. 视图 1.1 理论 [1] 什么是视图 视图是通过查询得到一张虚拟表,并保存下来,后续可以直接使用。 视图也是一张表。 在计算机科学中,视图(View)是一种虚拟表,其内容是一个或多个基本表的查询结果。 与基本表不同,视图不存储实际的数据,而是根据创建视图时的查询语句在…

车间工人违规行为智能识别方案

车间工人违规行为智能识别方案基于深度学习的视频分析系统,车间工人违规行为智能识别方案能够利用工业相机实时监测工人在生产线上的行为,系统不仅能够监测工人的操作行为,还能够监控整个生产流程。例如,它可以监测材料选择需要经过的环节数量,手动翻转的次数,以及上料动…

人员禁区闯入行为检测算法

人员禁区闯入行为检测算法通过现场监控相机捕捉监控区域内的实时图像,人员禁区闯入行为检测算法基于YOLOv7和CNN对图像进行分析,当检测到禁区闯入行为时,系统会立即触发告警。支持与第三方设备通信,发送开关量信号,以及将告警信息推送给后台值班人员。通过实时监控和快速响…

MySQL底层概述—1.InnoDB内存结构

大纲 1.InnoDB引擎架构 2.Buffer Pool 3.Page管理机制之Page页分类 4.Page管理机制之Page页管理 5.Change Buffer 6.Log Buffer1.InnoDB引擎架构 (1)InnoDB引擎架构图 (2)InnoDB内存结构(1)InnoDB引擎架构图 下面是InnoDB引擎架构图,主要分为内存结构和磁盘结构两大部分。(2)I…

[Vue] Watch and WatchEffect

WatchLet’s look at another simple example using our composition API. Here’s some code that has a simple search input box, uses the search text to call an API, and returns the number of events that match the input results. <template><div>Searc…

【java编程】Unsafe 类

Unsafe 类不是一个 ClassLoader, 但是为什么要在本篇文章提起, 其实是因为该类可以进行注入恶意类到 JVM 中. Unsafe 类简介 sun.misc.Unsafe 类是一个提供底层、不安全的操作,比如直接内存访问、线程调度、原子操作等功能的工具类。 这个类主要被Java内部库使用,比如Java的…

山体落石泥石流自动监测摄像机

山体落石泥石流自动监测摄像机捕获的图像数据将对图像进行分析,山体落石泥石流自动监测摄像机识别出山体的位移、裂缝、滑坡等异常现象。算法的训练需要大量的山体图像数据,包括正常和异常状态的图像,以确保其识别的准确性。一旦AI系统识别出山体失稳的迹象,它会立即触发报…

【java编程】Xalan ClassLoader

Xalan 是 Java 中用于操作 XML 的一个库,它是 Apache XML 项目的一部分,主要用于将 XSLT(Extensible Stylesheet Language Transformations)转换为可执行代码,从而实现XML文档的转换。 XSLT 的理解 当然了, 我们先理解该模块如何使用之后, 我们再研究它的妙用, XSLT 说白了…

[游记]CSP2024 游记

这是一篇迟到的游记,为什么呢?因为作者已经成为文化课选手了。 Day-1 晚上 \(6:00\) 到了宾馆,在路上准备了一下面基事宜。在车上昏昏沉沉,结果下了车精神抖擞了。 简单布置之后开始摆烂,这是符合考前规范的好事。某游戏连跪十五局。rp -- 。我希望这是给我第二天攒 rp。 …

[笔记]动态规划优化(斜率优化,决策单调性优化)

本文主要记录某些动态规划思路及动态规划优化。 首先先把以前写过的斜率优化祭出来。 斜率优化 \(\text{P5017 [NOIP2018 普及组] 摆渡车}\) 经典例题。 设 \(f_i\) 表示最后班车在 \(i\) 时刻发车,所有人等待时间和的最小值。(这里的所有人是指到达时刻小于等于 \(i\) 的所有…