【发布时间】:2020-01-09 00:38:57
【问题描述】:
我的理解是这段代码可以在文件中保存一个向量。
using Alloc = boost::interprocess::allocator<int32_t, boost::interprocess::managed_mapped_file::segment_manager>;
using Vec = boost::interprocess::vector<int32_t, Alloc>;
void f() {
boost::interprocess::managed_mapped_file seg(boost::interprocess::open_or_create, "data.dat", 1024);
auto vec = seg.find_or_construct<Vec>("vec")(seg.get_segment_manager());
// ......
}
但是,当向量试图获取太多字节时,它会抛出 bad_alloc 异常。
我无法预测需要多少字节,所以我想出在 free_memory 减少时增加文件。但是,有时会在增长时发生断言失败。
这是最少的代码。
using Alloc = allocator<int32_t, managed_mapped_file::segment_manager>;
using Vec = vector<int32_t, Alloc>;
void test(int, int);
int main()
{
test(4096, 4); // Change this value if not reproduced
return 0;
}
void test(int initialBytes, int extraBytes) {
fprintf(stderr, "test(%d, %d)\n", initialBytes, extraBytes);
remove("data.dat");
auto seg = make_unique<managed_mapped_file>(open_or_create, "data.dat", initialBytes);
auto vec = seg->find_or_construct<Vec>("vec")(seg->get_segment_manager());
fprintf(stderr, "vec->capacity=%ld\n", vec->capacity());
fprintf(stderr, "seg.get_free_memory()=%ld\n\n", seg->get_free_memory());
seg = nullptr;
fprintf(stderr, "tag1\n");
boost::interprocess::managed_mapped_file::grow("data.dat", extraBytes);
fprintf(stderr, "tag2\n");
seg = make_unique<managed_mapped_file>(open_only, "data.dat");
fprintf(stderr, "tag3\n");
vec = seg->find<Vec>("vec").first;
fprintf(stderr, "tag4\n");
fprintf(stderr, "vec->capacity=%ld\n", vec->capacity());
fprintf(stderr, "seg.get_free_memory()=%ld\n\n", seg->get_free_memory());
}
更小
void test(int initialBytes, int extraBytes) {
remove("data.dat");
auto seg = std::make_unique<managed_mapped_file>(open_or_create, "data.dat", initialBytes);
seg = nullptr;
managed_mapped_file::grow("data.dat", extraBytes);
}
问:如何在不假设最大尺寸的情况下存储弹性向量?
我误解了grow - 它是静态函数。所以我修复了代码。断言仍然失败。
我发现4 <= extraBytes && extraBytes < 24时断言失败
【问题讨论】:
-
通过编写自己的(复杂的)实现?共享内存映射总是根据所涉及的有限页数来定义。要实现真正的动态行为,您必须创建额外的映射。这与“正常” malloc 的工作方式并没有什么不同(在某个时间点,它还必须将内存“映射”到进程空间才能完成进一步的分配)。
-
@oakad 那么
grow做了什么?它不会关闭 mmf 并展开吗? -
在任何共享内存情况下都涉及多方。所有这些各方都必须以某种方式就共享内存范围进行同步。至于
grow,boost 文档非常清楚:只有在相关内存段未被任何人使用(0 个相关方)时它才有效。 -
@oakad 当我发现
grow是静态的时,我认为seg必须被释放。然后我修复了代码,但没有任何改变。除了共享内存与 mmf 之外,我在链接上找不到我的代码和示例之间的区别。
标签: c++ boost boost-interprocess