设计问题:std::map的线程安全

2023-12-01

我正在使用 std::map 来实现我的本地哈希表,该哈希表将同时被多个线程访问。 我做了一些研究,发现 std::map 不是线程安全的。 所以我将使用互斥体在地图上进行插入和删除操作。 我计划有单独的互斥锁,每个映射条目都有一个互斥锁,以便可以独立修改它们。

我是否需要将查找操作也放在关键部分下? 查找操作会受到插入/删除操作的影响吗? 有没有比使用 std::map 更好的实现来处理一切?


二叉树并不特别适合多线程,因为重新平衡可能会在树范围的修改中退化。此外,全局互斥体会对性能产生非常负面的影响。

我强烈建议使用已经编写的线程安全容器。例如,英特尔TBB包含一个concurrent_hash_map.

如果您愿意learn然而,这里有一些关于构建并发排序关联容器的提示(我相信完整的介绍不仅超出了我的能力范围,而且也不合适,在这里)。

读者/作家

您可能想要使用读取器/写入器互斥体,而不是常规互斥体。这意味着并行读取,而写入保持严格顺序。

Own Tree

您还可以构建自己的红黑树或 AVL 树。通过每个节点使用读取器/写入器互斥体来扩充树结构。这允许您仅阻止part即使在重新平衡时,也是树的一部分,而不是整个结构。eg键间隔足够远的刀片可以是平行的。

跳过列表

链接列表更适合并发操作,因为您可以轻松隔离modified zone.

A 跳过列表建立在这个优势的基础上,但增强了结构以通过密钥提供 O(log N) 访问。

遍历列表的典型方法是使用交过手习语,即在释放当前节点的互斥体之前获取下一个节点的互斥体。跳跃列表添加了第二个维度,因为您可以在两个节点之间潜水,从而释放这两个节点(并让其他步行者走在您前面)。

实现比二叉搜索树简单得多。

执着的

另一个有趣的部分是持久(或半持久)数据结构的想法,通常在函数式编程中找到。二叉搜索树特别适合它。

基本思想是节点(或其内容)一旦存在就永远不会更改。您可以通过共享一个可变的head,这将指向更高版本。

  • 读取:复制当前头,然后放心使用(信息不可变)
  • 写入:您要在常规树中修改的每个节点都会被复制并修改副本,因此您每次都会重建树的一部分(直到根),并更新head指向新的根。有一些有效的方法可以在下降树时重新平衡。写入是连续的

主要优点是地图版本始终可用。也就是说,你可以随时read即使另一个线程正在执行插入或删除。此外,因为read访问只需要一个同时读(复制根指针时),它们接近无锁,因此具有出色的性能。

引用计数(固有的)是这些节点的朋友。

注意:树的副本非常便宜:)


我不知道 C++ 中并发跳过列表或并发半持久二叉搜索树的任何实现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计问题:std::map的线程安全 的相关文章

  • 静态构造函数和 BeforeFieldInit?

    如果类型没有静态构造函数 则将执行字段初始值设定项 就在使用该类型之前 或者在某个时间点突发奇想 运行时 为什么这段代码 void Main start Dump Test EchoAndReturn Hello end Dump clas
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • C# 中一次性对象克隆会导致内存泄漏吗?

    检查这个代码 class someclass IDisposable private Bitmap imageObject public void ImageCrop int X int Y int W int H imageObject
  • Unity手游触摸动作不扎实

    我的代码中有一种 错误 我只是找不到它发生的原因以及如何修复它 我是统一的初学者 甚至是统一的手机游戏的初学者 我使用触摸让玩家从一侧移动到另一侧 但问题是我希望玩家在手指从一侧滑动到另一侧时能够平滑移动 但我的代码还会将玩家移动到您点击的
  • Libev,如何将参数传递给相关回调

    我陷入了 libev 中争论的境地 通常 libev 在类似的函数中接收包 接收回调 没关系 但是实际操作中 我们需要派遣一个亲戚 写回调 根据收到的包裹处理具体工作 例如 S RECV MSG pstRecvMsg S RECV MSG
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • 如何在 Javascript 中连接 C# ActiveX 事件处理程序

    我尝试使用几个代码片段将 ActiveX 对象与 Javascript 事件处理程序挂钩 我无法确定为什么事件处理程序没有被调用 带有项目的 Github 存储库 https github com JesseKPhillips Csharp
  • 如何防止 Blazor NavLink 组件的默认导航

    从 Blazor 3 1 Preview 2 开始 应该可以防止默认导航行为 https devblogs microsoft com aspnet asp net core updates in net core 3 1 preview
  • 我们可以通过指针来改变const定义的对象的值吗?

    include
  • 读取依赖步行者输出

    I am having some problems using one of the Dlls in my application and I ran dependency walker on it i am not sure how to
  • .NET 和 Mono 之间的开发差异

    我正在研究 Mono 和 NET C 将来当项目开发时我们需要在 Linux 服务器上运行代码 此时我一直在研究 ASP NET MVC 和 Mono 我运行 Ubuntu 发行版 想要开发 Web 应用程序 其他一些开发人员使用 Wind
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • Unity3D - 将 UI 对象移动到屏幕中心,同时保持其父子关系

    我有一个 UI 图像 它的父级是 RectTransform 容器 该容器的父级是 UI 面板 而 UI 面板的父级是 Canvas 我希望能够将此 UI 图像移动到屏幕中心 即画布 同时保留父级层次结构 我的目标是将 UI 图像从中心动画
  • 每个客户端一个线程与线程服务器的排队线程模型之间的相对优点?

    假设我们正在构建一个线程服务器 旨在在具有四个核心的系统上运行 我能想到的两种线程管理方案是每个客户端连接一个线程和一个排队系统 正如第一个系统的名称所暗示的那样 我们将为每个连接到服务器的客户端生成一个线程 假设一个线程始终专用于程序的主
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • 如果将变量设置为等于新对象,旧对象会发生什么?

    假设我们有一个 X 类not有一个超载的operator 功能 class X int n X n 0 X int n n n int main X a 1 an object gets constructed here more code
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配
  • 如何为有时异步的操作创建和实现接口

    假设我有数百个类 它们使用 计算 方法实现公共接口 一些类将执行异步 例如读取文件 而实现相同接口的其他类将执行同步代码 例如将两个数字相加 为了维护和性能 对此进行编码的好方法是什么 到目前为止我读到的帖子总是建议将异步 等待方法冒泡给调

随机推荐

  • PHP通过html标签分解字符串

    假设字符串 a 成立 p Phasellus blandit enim eget odio euismod eu dictum quam scelerisque p p Sed ut diam nisi p p Ut vestibulum
  • ssis 中的参数绑定

    如何使用执行包任务动态地将值传递给子包变量 我需要同时从另一个包 父包 调用一个包 子包 在每次调用中 我都需要将不同的值传递给子包变量 I have tried using parameter bindings in Execute Pa
  • 如何让 Phoenix 监听 IPv6?

    我正在努力寻找有关让 Phoenix 以及 Cowboy 和 Ranch 同时监听 IPv4 和 IPv6 的信息 我在 Ubuntu 16 04 的 VPS 上运行 它同时具有 IPv4 和 IPv6 地址 跑步时netstat tulp
  • 在单独的线程中关闭相机设备

    我正在使用 Android Camera2 创建自定义相机 cameraDevice close 方法速度很慢 并且会使 UI 冻结 1 秒 我把它放在另一个线程中 看起来效果很好 我想知道这是否会导致一些严重的问题以及是否有其他方法可以实
  • omp_set_num_threads(1) 比没有 openmp 慢的原因

    相信大家都同意这篇文章的标题 有人能指出我的原因吗 有没有参考书之类的 我试图找到但没有运气 我相信原因是 openmp 有同步开销 没有 openmp 项目没有 希望有人能进一步扩展原因吗 Thanks 虽然即使只有一个线程 使用 Ope
  • BigQuery:如何将库加载到java代码中

    我是 Bigquery 的新开发人员 我正在遵循教程https developers google com bigquery bigquery api quickstart带有 Java 代码和导入的库https developers go
  • JVM是否保证缓存非易失性变量?

    JVM是否保证缓存非易失性变量 程序员是否可以依赖 JVM 始终在本地为每个线程缓存非易失性变量 或者 JVM 可能会也可能不会这样做 因此程序员不应该依赖 JVM 来做到这一点 感谢您提前的答复 不 JVM 不保证非易失性字段的 缓存 J
  • Gremlin - 随机选择一项

    将我视为 用户 1 查询的目的是获取我关注的人 发布 的帖子 并对每个帖子进行检查 是否已被我喜欢过 我关注的其他人是否喜欢它 如果是随机选择其中一位用户返回 样本数据 g addV user property id 1 as 1 addV
  • OpenCV 从标准输入加载图像/视频

    我正在尝试使用以下代码从 stdin 读取 jpg 图像 int c count 0 vector
  • 在 Xcode 7 中构建 Parse 时出现链接错误

    我正在尝试将 Parse com SDK 添加到我的 Xcode 7 项目中 我已经遵循了入门指南 并且之前已经在 Xcode 6 中成功做到了 然而 这次当我尝试构建时 我收到了此错误消息 ld framework not found B
  • 列表视图列标题不显示 VB.Net

    我没有在 listView 中获取列标题 仅显示一项 0 不显示子项 这是我的代码 告诉我其中有什么问题 先感谢您 Dim PTCode As Integer CInt ChildPatnameTag ClearSQl CheckState
  • 部署项目中的安装目录

    我正在开发一个应用程序 我将在部署项目 将创建一个安装程序 的帮助下部署它 在安装程序的一个步骤中 用户将允许更改应用程序的安装文件夹 我需要知道这个文件夹是什么 因为那里保存了一些我需要从另一个 DLL 文件中使用的文件 如何以编程方式获
  • AutoCompleteTextView 未从 Google Places API 获取建议

    这是我从 Google Places API 获取地点建议的代码 但它显示一些错误 例如 无法连接到 Google Places API 我已经给出了在这段代码的底部得到的正确错误 我只需要一个 AutoCompleteTextView 来
  • 是否可以在 java (log4j) 中记录方法调用?

    是否可以在 log4j Java 中记录任何方法调用 Thanks 不 如果不编辑调用站点或方法本身就不行 我认为您所追求的是面向方面的编程 看一下AspectJ例如
  • 使用 Nodejs 实时抓取聊天记录

    我想做的是建立一个scrapingNodeJs 上的应用程序 它可以实时监控聊天并将某些消息存储在任何数据库中 我想做的是以下内容 我想从聊天平台流中捕获数据 从而捕获一些有用的信息来帮助那些正在做流媒体服务的人 但我不知道如何开始使用 N
  • Python unicode 解码错误 SUD

    好的 我有 coding utf 8 在我的脚本的顶部 它可以从数据库中提取数据 其中包含有趣的字符 并将该数据存储到变量中 但是我遇到其他问题 请参阅我提取数据 组织它 然后将其转储到变量中 如下所示 title product 1 Wh
  • 通过 Web 应用程序启动 Spark 应用程序的最佳实践?

    我想通过 Web 应用程序向用户公开我的 Spark 应用程序 基本上 用户可以决定他想要运行哪个操作并输入一些变量 这些变量需要传递到 Spark 应用程序 例如 用户输入几个字段 然后单击一个按钮 该按钮执行以下 运行火花应用1带参数
  • `eli5.show_weights` 显示的标准差与 `feature_importances_std_` 中的值不一致

    The PermutationImportance对象有一些很好的属性 例如feature importances and feature importances std 为了以 HTML 样式可视化此属性 我使用了eli5 show we
  • THREE.js 动态添加点到 Points 几何体不渲染

    我正在使用 Three js r83 我试图动态地将点添加到几何体中 但场景永远不会更新 这有效 var tmaterial new THREE PointsMaterial color 0xff0000 size 5 opacity 1
  • 设计问题:std::map的线程安全

    我正在使用 std map 来实现我的本地哈希表 该哈希表将同时被多个线程访问 我做了一些研究 发现 std map 不是线程安全的 所以我将使用互斥体在地图上进行插入和删除操作 我计划有单独的互斥锁 每个映射条目都有一个互斥锁 以便可以独