【发布时间】:2013-12-03 05:35:43
【问题描述】:
我有一个有趣的挑战,对于那些在无锁数据结构和基于磁盘的数据结构方面具有深厚背景的人。
我正在寻找一种在 C++ 中构建数据结构以保存不同数量对象的方法。
限制是这样的:
- 数据结构必须驻留在磁盘上。
- 有一个线程写入数据结构,许多其他线程从中读取。
- 每次读取都是原子的。 (假设我可以为此自动读取大小为 32/64KB 的块,并且所有对象的大小都小于该大小。
- 写入不应阻塞读取,因为可以假设我也可以以原子方式写入 32/64KB 的块。
- 锁根本不能用。
有什么建议吗?
我正在考虑使用 B-Tree 之类的东西,当需要拆分节点并写入新数据而不是将它们移动到文件末尾的新节点,然后只需更新指向将驻留的节点的指针,例如在其他文件中(原始块将被标记为免费并添加到免费存储中)
但是,如果我的映射文件大于 32/64Kb,我会遇到问题。假设我希望它只保存 100 万个对象指针,而不是 4 字节/指针我得到 400 万字节,大约是4 Megs...(还有 10 亿个对象甚至更多...)这意味着映射文件不能以原子方式写入。
因此,如果有人对如何实现上述内容有更好的建议 - 甚至是某个方向,将不胜感激。
据我所知,B-Tree 的所有开源/商业实现都使用某种类型的锁,我无法使用。
谢谢, 最大。
【问题讨论】:
-
但是你真的需要写整个地图文件吗?仅更新已更改的块还不够吗?
-
我看不出没有锁你怎么能做到这一点......
-
这在您描述的方式中是不可能的,因为 OS 文件访问 API 隐式具有读写器类型的锁定 - 即您基本上使用 OS 的互斥锁而不是您自己的。
-
正如@DarkWanderer 所说,操作系统将使用锁来防止对磁盘的并发访问。您可能应该使用内存映射文件并查看无锁 B-Tree 实现。 cs.umanitoba.ca/~hacamero/Research/BtreeTechrpt2011.pdf 读起来很有趣。另外,出于好奇,为什么禁止使用锁?
-
我无法在同一个句子中理解“无锁”和“磁盘”。
标签: c++ multithreading data-structures b-tree lock-free