并发数据结构设计

2024-03-26

我正在尝试提出用于高吞吐量 C++ 服务器的最佳数据结构。该数据结构将用于存储从几到几百万个对象的任何内容,并且不需要排序(尽管可以非常便宜地提供唯一的排序键)。

要求是它能够支持高效的插入(最好是 O(1))、中等效率的删除和高效的遍历。它不需要支持查找操作(删除可能需要的除外)。

不同之处在于,当其他线程枚举数据结构时,它对于修改必须是线程安全的。这意味着简单的红黑树不起作用,因为一个线程无法在不弄乱其他线程持有的任何游标的情况下插入元素(并执行必要的树旋转)。

It is not使用读/写锁并推迟写操作直到所有读者都完成是可以接受的,因为读操作可能会长期存在。当有读者存在时发生的插入对于该读者是否可见并不重要。

内存占用也很重要,显然越小越好!

有哪些建议?

对评论的回应:

感谢您的回答。

不,插入不能使现有迭代器无效。迭代器可能会也可能不会看到新的插入,但它们必须看到如果插入没有发生时它们会看到的所有内容。

删除是必需的,但是由于更高级别的规则,我可以保证迭代器永远不会在可删除的项目上停止。

为游标锁定每个节点会对性能产生太大影响。可能有多个线程同时读取,并且多个线程在锁中使用的任何类型的内存热点都会杀死内存带宽(正如我们艰难地发现的那样!)。即使使用调用 InterlockedIncrement 的多个线程进行简单的读取器计数也无法完全扩展。

我同意链接列表可能是最好的方法。删除很少见,因此为支持 O(1) 删除而支付后向指针的内存代价是昂贵的,我们可以根据需要单独计算它们,因为删除往往是批量操作。

幸运的是,插入链表不需要读者进行任何锁定,只要在头指针更改之前更新插入节点中的指针即可。

锁定-复制-解锁的想法很有趣。所涉及的数据量太大,无法作为读者的默认设置,但当作家与读者发生冲突时,它可以用于作家。读/写锁将保护整个结构,并且如果与读取器发生冲突,则写入将克隆数据结构。写入比读取少得多。


就我个人而言,我非常喜欢高并发情况下的持久不可变数据结构。我不知道有什么专门针对 C++ 的,但是 Rich Hickey 在 Java 中创建了一些优秀的(而且速度极快)不可变的数据结构Clojure http://clojure.org。具体来说:向量、哈希表和哈希集。它们并不难移植,因此您可能需要考虑其中之一。

更详细地说,持久不可变数据结构确实解决了许多与并发相关的问题。因为数据结构本身是不可变的,所以不存在多线程并发读取/迭代的问题(只要是const迭代器)。 “写入”也可以是异步的,因为它并不是真正写入现有结构,而是创建包含新元素的该结构的新版本。此操作变得高效(O(1)在希基的所有结构中),因为您实际上并没有复制所有内容。每个新版本的大部分结构都与旧版本相同。这使得内存效率更高,并且比简单的写时复制技术显着提高了性能。

对于不可变的数据结构,真正需要同步的唯一时间是实际写入引用单元格。由于内存访问是原子的,因此通常也可以是无锁的。这里唯一需要注意的是,您可能会在线程之间丢失数据(竞争条件)。数据结构永远不会因并发而损坏,但这并不意味着在两个线程基于单个旧版本结构创建新版本并尝试写入其结果的情况下,不一致的结果是不可能的(其中一个将“赢”,而对方的更改将丢失)。为了解决这个问题,你要么需要一个“写操作”锁,要么使用某种STM http://en.wikipedia.org/wiki/Software_transactional_memory。我喜欢第二种方法,它可以在低冲突系统中实现易用性和吞吐量(理想情况下,写入是非阻塞的,读取是理想的)never块),但其中任何一个都可以工作。

你问了一个棘手的问题,但实际上并没有一个好的答案。并发安全的数据结构很难编写,特别是当它们需要可变时。在存在共享状态的情况下,完全无锁的架构被证明是不可能的,因此您可能想要放弃该要求。您能做的最好的事情就是最大限度地减少所需的锁定,从而减少不可变的数据结构。

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

并发数据结构设计 的相关文章

随机推荐

  • 在 .NET Core 项目中添加 PDF 链接

    我想将 PDF 文件添加到我的 net core 2 0 项目中 它在我的本地主机上使用 IIS Express 运行 我已经将 pdf 文件添加到我的项目文件中 它显示在解决方案资源管理器中 并且我在中添加了相应的链接我的 cshtml
  • HTML5视频播放器:动态加载视频

    那么 使用兼容 HTML 5 的视频播放器 如 Video JS 如何动态加载视频 而无需重新加载整个页面呢 想象一下 一个链接列表 类似于播放列表 每个链接都指向一个视频 单击链接时 我想将所选视频加载到播放器中 目前 我正在使用一个包含
  • 在vim中打开目录

    我是一名 mac 用户 正在认真尝试 vim 我习惯的大多数 GUI 编辑器都允许我通过执行以下命令来将目录作为 项目 打开 编辑 www example com vim 等效项vim www example com 将显示目录中的文件列表
  • 如何将 STDERR 重定向到 STDOUT,但忽略原始 STDOUT? [复制]

    这个问题在这里已经有答案了 我有一个程序STDERR我想要检查并运行的输出grep on etc 所以我可以将其重定向到STDOUT并使用 grep 但问题是 我这样做not想要原件STDOUT内容 所以 这个不行 cmd 2 gt 1 g
  • 为什么选择静态类而不是单例实现?

    静态与静态 单例问题之前在 SO 中已经讨论过很多次了 然而 所有的答案都指出了单例的许多优点 我的问题是 静态类比单例有什么优点 为什么不每次都简单地选择一个单例呢 静态类是你盒子里的一个技术工具 基本上是一个语言功能 Singleton
  • SQL聚合函数选择唯一值

    我有一个包含两列的行集 technical id and natural id 行集实际上是复杂查询的结果 假设列值之间的映射是双射的 即对于具有相同值的两行 technical id the natural ids 也相同 对于不同的te
  • iPhone 应用程序可以阻止电话吗?

    是否可以编写一个应用程序来阻止传入和传出的电话 还是 iPhone 被锁定太多了 谢谢 编辑 请参阅下面 Rajan Maheshwari 的回答 CallKit 现在提供了这一点 即使那些看似永远不会改变的事情 最终也可能会改变 任何修改
  • Django 从 postgres JSON 字段获取值

    我有一个简单的模型 例如 class MyModel models Model data JSONField JSON 字段data结构如下 name Brian skills id 4 name First aid id 5 name S
  • 如何删除 Visual Studio PIN TAB 图标(显然在选项卡上)

    有没有办法完全删除 Visual Studio 2010 中的 pin 选项卡选项 如何 我一直不小心点击它 我希望它消失 我从不使用它并且总是不小心点击它 thnx 附注右键单击 PIN 图标确实会弹出一些自定义对话框 但无法删除它 无法
  • SimpleHTTPServer 添加 default.htm default.html 到索引文件

    我总是用 python m SimpleHTTPServer对于快速本地静态 Web 测试 它非常适合index htm or index html作为索引文件 不过我需要使用default htm or default html对于我目前
  • Sequelize cli 模型创建

    我一直在尝试创建一个user model使用sequelize cli 但每当我插入更多参数 如主键和唯一 时 解析器就会失败 例如 npx sequelize model create name user attributes name
  • 通过序言格式化 csv 表?

    尽我所能 我无法弄清楚如何更改 sphinx 的 pdf 输出中的默认表格格式 我可以编辑 tex 文件或 writer py 源代码 但这两个似乎都是不好的选择 有什么东西可以通过序言来实现这一点吗 取决于您试图通过更改表格格式来完成的任
  • OWL 中表达式前面的列表?

    OWL 中表达式前面是否可以有一个列表 就像是 Dairy Egg Nut rdfs subClassOf FoodGroup or Dairy Egg Nut rdfs subClassOf FoodGroup 或者一般来说 是否存在针对
  • PHP 日期时间字符串区分

    在这两种情况下 我都可以从字符串创建日期对象 如下所示 dt strtotime 2013 04 19 17 00 00 or dt strtotime 10 hours 我需要一种方法来区分这两种日期类型 无论是相对数据字符串还是绝对数据
  • Windows 7 上的全屏 OpenGL 窗口打开的模态对话框不显示

    看来我的问题可能与未回答的相关问题相同 Windows 7 上出现 GLUT 的 OpenGL 全屏模式不显示消息框 https stackoverflow com questions 1842312 opengl with glut on
  • Ajax 追加加载

    它必须是jquery 我有文件 text html 其中有 6 个 div a b c d e f 在另一个文件中 我有一个 div 我喜欢它将 a b c d e f 的内容填充到该单个 div 中 我尝试过 load 但 b 替换了 a
  • ImageMagick - “未找到 CORE_RL_magick_.dll”或如何使用 ruby​​ 1.9.2 在 Windows 上安装 RMagick

    我正在开发 Rail3 应用程序 经过几个小时的努力 终于在 win7x64 ruby 1 9 2 上安装了 rmagick 2 13 1 gem 没有错误 我遇到了另一个错误 是的 我听说 Windows 中的 Rails 体验可能会很痛
  • 按一天中的时间自动切换 Windows 10 中的暗/亮模式(无需修改或更改主题!)

    如今大多数设备都允许自动切换暗 亮模式 但 Windows 10 似乎没有这样的功能 有办法做到这一点吗 例如使用任务计划程序 似乎有很多关于如何以编程方式更改窗口 主题 的示例 但没有关于亮 暗模式切换的示例 可以在 设置 颜色 中为 W
  • jQuery 圆函数

    如何使用 jQuery 对数字进行四舍五入 如果数字是 3168 我想将其打印为 32 或者 如果数字为 5233 则结果应为 52 我怎样才能做到这一点 我应该使用Math round功能 是的 您应该使用 Math round 除以 1
  • 并发数据结构设计

    我正在尝试提出用于高吞吐量 C 服务器的最佳数据结构 该数据结构将用于存储从几到几百万个对象的任何内容 并且不需要排序 尽管可以非常便宜地提供唯一的排序键 要求是它能够支持高效的插入 最好是 O 1 中等效率的删除和高效的遍历 它不需要支持