当前位置: 首页 > 面试题库 >

快速调整mmap文件的大小

公良凯
2023-03-14
问题内容

我需要一个非常大的mmap文件的无拷贝调整大小,同时仍然允许并发访问读取器线程。

一种简单的方法是在同一进程中在同一文件上使用两个MAP_SHARED映射(增长文件,然后创建第二个映射,其中包括增长的区域),然后在所有可访问该文件的读取器完成操作后取消映射旧映射。但是,我很好奇下面的方案是否可行,如果可行,是否有任何好处。

  1. 使用MAP_PRIVATE映射文件
  2. 对多个线程进行只读访问
  3. 要么为文件获取一个互斥锁,然后将其写入内存(假设这样做是为了使可能正在读取该内存的读者不会被它弄乱)
  4. 或获取互斥锁,但增加文件的大小并使用mremap将其移动到新地址(调整映射的大小,而无需复制或不必要的文件IO。)

疯狂的部分出现在(4)。如果您移动内存,旧地址将变为无效,并且仍在读取的读取器可能会突然出现访问冲突。如果我们修改读取器以捕获此访问冲突,然后重新启动操作(即,不要重新读取错误的地址,请给定偏移量的地址和mremap的新基址来重新计算),该怎么办?是的,我知道这很邪恶。
,但在我看来,读者只能成功读取旧地址上的数据,否则会因访问冲突而失败并重试。如果采取足够的措施,那 应该
安全的。由于调整大小不会经常发生,因此读者最终会成功,并且不会陷入重试循环中。

如果在阅读器仍具有指向旧地址空间的指针的情况下重新使用该旧地址空间,则可能会发生问题。这样就不会出现访问冲突,但是数据将是不正确的,程序将进入未定义行为的独角兽和糖果填充区(其中通常既没有独角兽也没有糖果)。

但是,如果您完全控制了分配并且可以确定在此期间发生的任何分配都不会再使用旧的地址空间,那么这应该不成问题,并且行为也不应不确定。

我对吗?能行吗?与使用两个MAP_SHARED映射相比,这有什么好处吗?


问题答案:

对于我来说,很难想象您不知道文件可以多大的上限。假设是这样,您可以通过在首次使用mmap()映射文件时提供该大小来“保留”文件的最大大小。当然,超出文件实际大小的任何访问都将导致访问冲突,但这就是您无论如何都希望其工作的方式-
您可能会争辩说,保留额外的地址空间 可确保 访问冲突,而不是使该地址范围不开放被诸如mmap()或malloc()之类的其他调用所使用。

无论如何,关键是我的解决方案,您永远不会 移动 地址范围,只更改其大小,现在锁定就在为每个线程提供当前有效大小的数据结构周围。

如果文件太多,则每个文件的最大映射都使您用尽了地址空间,那么我的解决方案将不起作用,但是这是64位地址空间的使用期限,因此希望最大映射大小没有问题。

(只是为了确保我不会忘记一些愚蠢的东西,我确实写了一个小程序说服自己,当您尝试访问超出文件大小的文件时,创建大于文件大小的映射会导致访问冲突,然后可以正常工作一旦将文件ftruncate()变大,所有文件都将从第一次mmap()调用返回的地址相同。)



 类似资料:
  • 问题内容: 我有一个具名的,不需要让用户调整其大小。当然,我可以在每次用户尝试时重新调整它的大小,但是有什么办法不让用户将窗口打开到全屏或拉伸窗口呢? 问题答案: 编辑/更新: Xcode 10.2•Swift 5 NSWindow具有一个称为styleMask的属性,该属性使您可以控制用户可以使用哪种控件。如果不想让用户调整窗口大小,则必须使用mutating方法删除样式掩码.resizable

  • 问题内容: 在Windows上的Python中,我可以通过创建一个大文件 现在大约是1 GB。但是,在Linux上,这将返回。 有没有办法在Linux上获得与Windows相同的行为?也就是说,能够使用?来增加文件的大小。 问题答案: 至少在POSIX系统上,不能用于增加(或减小)文件的大小。的功能是将文件的一部分映射到内存。合乎逻辑的是,您请求映射的东西应该确实存在!坦白说,我真的很惊讶您实际上

  • 问题内容: 我想使用python快速找到任何文件夹的总大小。 这是我编写的用于获取文件夹总大小的简单脚本,大约花费了60秒(+ -5秒)。通过使用多处理,我在四核计算机上将其缩短到23秒。 使用Windows文件浏览器仅需约3秒钟(右键单击->属性即可自行查看)。那么,有没有一种更快的方法来找到文件夹的总大小,使其接近Windows可以达到的速度? Windows 7,python 2.6(搜索,

  • 应用自动对比度调整 “自动对比度”命令将自动调整图像对比度。由于“自动对比度”不会单独调整通道,因此不会引入或消除色痕。它剪切图像中的阴影和高光值,然后将图像剩余部分的最亮和最暗像素映射到纯白(色阶为 255)和纯黑(色阶为 0)。这会使高光看上去更亮,阴影看上去更暗。 默认情况下,在标识图像中的最亮和最暗像素时,“自动对比度”将剪切白色和黑色像素的 0.5% -- 也就是说,忽略两个极端像素值的

  • 但我想知道如何选择我希望的支点,例如在这个整数列表中,8、7、1、9、11、5、6,我希望选择键6作为我代码中的支点。或者我想选9或者其他什么。我怎样才能把它写进我的代码?非常感谢任何帮助。

  • 问题内容: 我需要将包含4个字节整数(小尾数)的二进制文件读入我的Android应用程序的2D数组中。我当前的解决方案如下: 对于2k * 2k的阵列,这非常慢,大约需要25秒。我在DDMS中可以看到垃圾收集器正在加班,因此这可能是速度缓慢的原因之一。 必须有一种使用ByteBuffer将该文件读入数组的更有效的方法,但是目前我看不到它。关于如何加快速度的任何想法? 问题答案: 为什么不读入4字节