如果我有类似绳索的数据结构:
struct rope {
struct { char *buf; size_t len; } *segments;
size_t len;
}
有没有办法将每个段的缓冲区连续映射到虚拟内存空间,而无需复制?我的用例是以最有效的方式将绳索转换为弦。
以下是如何使用它的示例:
char *s = rope_flatten(r);
printf("%s\n", s);
r.segments[0].buf[4] = 'x';
printf("%s\n", s); // The 5th character is now replaced with 'x'
不用说,缓冲区(至少是映射的位)不会被NUL终止。
我知道这可能是特定于平台的。如果有符合POSIX标准的东西会很棒。如果没有,Linux是我的主要目标,如果不支持,我可以回到malloc和memcpy。
答案 0 :(得分:2)
在一个完美的世界中,你可以照常创建你的绳索并再次重新映射每个片段,这样你就可以看到它们是连续的第二个视图。如果您编辑一个段,没有问题,它将镜像到另一个视图。如果放大一个段,缓冲区将被透明更新。
然而,一些问题使得这一点变得不可行:
但是仍然存在将多个视图映射到地址空间的用例,即当数据发生变化而不是数据 structure 时,就像使用环形缓冲区一样:
通常情况下,你必须在软件中实现你的环绕逻辑,但如果你之后再次重新映射环形缓冲区的页面,你就可以获得一个只能memcpy
开启的环形缓冲区。 GNU Radio采用这种机制,上面有一篇很好的博文:
https://www.gnuradio.org/blog/buffers/
这篇博文让我很好奇,所以我在libvas重新实现了Linux,Windows和macOS的机制。如果你愿意,请查看。