相关疑难解决方法(0)

快速调整mmap文件的大小

我需要一个非常大的mmap文件的无副本重新大小,同时仍然允许并发访问读取器线程.

简单的方法是在同一个文件中使用两个MAP_SHARED映射(增长文件,然后创建包含增长区域的第二个映射),然后在所有可以访问它的读者完成后取消映射旧映射.但是,我很好奇下面的方案是否有效,如果有的话,它是否有任何优势.

  1. 使用MAP_PRIVATE mmap一个文件
  2. 在多个线程中对此内存进行只读访问
  3. 获取文件的互斥锁,写入内存(假设这是以读者可能正在读取内存的方式完成的,不会被它搞砸)
  4. 或获取互斥锁,但增加文件的大小并使用mremap将其移动到新地址(调整映射大小而不复制或不必要的文件IO.)

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

如果在读取器仍具有指向它的指针时重新使用旧地址空间,则可能会出现问题.然后将没有访问冲突,但数据将是不正确的,并且程序进入不确定行为的独角兽和糖果填充的土地(其中通常既没有独角兽也没有糖果.)

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

我对吗?这可行吗?使用两个MAP_SHARED映射是否有任何优势?

c c++ linux mmap

9
推荐指数
1
解决办法
8291
查看次数

如何实现动态共享内存大小调整?

当前,我想使用shm_open来获取文件描述符,然后在想向共享内存中添加新缓冲区时使用ftruncate和mmap。每个缓冲区分别用于其自身目的。

现在,我需要做的是任意调整缓冲区大小。munmap缓冲区也将在以后再次使用可用空间。

对于第一个问题,我只能提出的唯一解决方案是:ftuncate(file_size + old_buffer_size + extra_size),mmap,将整个数据复制到新缓冲区中,然后对原始数据进行映射。这对我来说看起来非常昂贵,并且可能有更好的方法。它还需要每次删除原始缓冲区。

对于第二个问题,我什至没有一个不好的解决方案,每次清除缓冲区时,我显然都无法移动内存。而且,如果我跟踪空闲内存并在任何可能的地方使用它,将会减慢分配过程的速度,并留给我剩余的零碎内存。

我希望这不要太令人困惑。谢谢

c memory-management resize mmap shared-memory

5
推荐指数
1
解决办法
1941
查看次数

标签 统计

c ×2

mmap ×2

c++ ×1

linux ×1

memory-management ×1

resize ×1

shared-memory ×1