【问题标题】:Get the copy-on-write behaviour of fork()ing, without fork()获取 fork()ing 的写时复制行为,无需 fork()
【发布时间】:2012-06-15 11:16:57
【问题描述】:

我有一个很大的缓冲区:

char *buf = malloc(1000000000); // 1GB

如果我派生了一个新进程,它将有一个与父进程共享内存的 buf,直到其中一个或另一个写入它。即使这样,内核也只需要分配一个新的 4KiB 块,其余的将继续共享。

我想制作一个 buf 的副本,但我只会更改一点副本。我想要不分叉的写时复制行为。 (就像你在分叉时免费获得一样。)

这可能吗?

【问题讨论】:

  • 当然可以,但它不会是“免费的”——您必须自己管理内存并跟踪更改。
  • 是的,我想要“免费”。我想知道是否有任何基于 mmap 的解决方案,或者我什至没有想到的解决方案。
  • 也许带有 MAP_ANONYMOUS 和 MAP_PRIVATE 的 mmap 可以完成这项工作?
  • 1000000000 字节不是 1 GB。应该是1073741824 (1024 * 1024 * 1024)。

标签: c fork copy-on-write


【解决方案1】:

您需要在磁盘或 POSIX 共享内存段 (shm_open) 上为该块创建一个文件。第一次,用MAP_SHARED 映射它。当您准备好复制并切换到 COW 时,再次调用 mmap 并使用 MAP_FIXEDMAP_PRIVATE 映射到原始地图的顶部,并使用 MAP_PRIVATE 制作第二个副本。这应该可以得到你想要的效果。

【讨论】:

  • 这看起来非常令人鼓舞,但我无法让它发挥作用。我收到一个总线错误(在第 13 行)。 fd == 3. 你能指出我的愚蠢错误吗? gist.github.com/2924412
  • 您需要ftruncate 为共享内存段指定大小。初始大小为零。
  • 谢谢,我添加了一个 ftruncate,现在有一个段错误而不是总线错误,仍然在第 14 行。
  • 我怀疑崩溃实际上是在您写入缓冲区的第 17 行。您的调试 printf 没有用,因为您没有刷新输出,它们甚至没有以 \n.. 结尾
  • 有效! gist.github.com/2924412 注释掉的 buf 重新映射的意义何在?我似乎不需要它。非常感谢。
猜你喜欢
  • 2020-04-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2017-06-27
  • 1970-01-01
相关资源
最近更新 更多