boost共享内存中的动态二维阵列创建
我想使用boost在共享内存中存储一个二维数组。 我不知道这个数组在编译时的大小,只知道在运行时 实现这一目标的最佳方式是什么boost共享内存中的动态二维阵列创建,boost,shared-memory,Boost,Shared Memory,我想使用boost在共享内存中存储一个二维数组。 我不知道这个数组在编译时的大小,只知道在运行时 实现这一目标的最佳方式是什么 有些代码会很受欢迎也许您可以将多数组与boost::interprocess::allocator一起使用。这需要多\u数组支持有状态分配器 如果没有,您可以按任何方式手动分配内存,并使用: multi_array_ref是一种多维容器适配器。它在任何连续的元素块上提供多数组接口。multi_array_ref导出与multi_array相同的接口,但构造函数除外 正在
有些代码会很受欢迎也许您可以将
多数组
与boost::interprocess::allocator
一起使用。这需要多\u数组
支持有状态分配器
如果没有,您可以按任何方式手动分配内存,并使用:
multi_array_ref是一种多维容器适配器。它在任何连续的元素块上提供多数组接口。multi_array_ref导出与multi_array相同的接口,但构造函数除外
正在尝试multi_数组
使用multi_array
会失败,因为它在内部不支持富指针(offset_ptr
而不是double*
)
因此,使用multi\u array\u ref
将符合以下顺序:
演示multi\u array\u ref
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& backing = *seg.find_or_construct<Vector<double> >("my_backing")
(rows*cols, seg.get_segment_manager());
// ensure enough backing storage
backing.resize(rows*cols); // previous runs might have required less
backing.shrink_to_fit(); // optional: might not be optimal
boost::multi_array_ref<double, 2> data(
backing.data(),
boost::extents[rows][cols]);
fmt::print("shape: {} num_elements(): {} free in segment: {}\n",
std::vector(data.shape(), data.shape()+2),
data.num_elements(),
seg.get_free_memory()
);
std::iota(data.origin(), data.origin() + data.num_elements(), 1);
fmt::print("{}\n", fmt::join(data, "\n"));
}
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
template <typename T>
using Matrix = Vector<Vector<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& nested = *seg.find_or_construct<Matrix<double> >("manual_nested_vectors")
(seg.get_segment_manager());
// ensure enough nested storage
nested.clear();
nested.shrink_to_fit();
nested.assign(rows, Vector<double>(cols, seg.get_segment_manager())); // not very efficient
fmt::print("shape: {}x{} total elements: {} free in segment: {}\n",
rows, cols,
rows*cols,
seg.get_free_memory()
);
size_t base = 1;
for(auto& row : nested) {
std::iota(row.begin(), row.end(), base);
base += cols;
}
fmt::print("{}\n", fmt::join(nested, "\n"));
}
或者,在后续运行中:
或者,使用嵌套向量
这会带来更多的碎片风险,索引功能不如Boost Multi-Array强大,而且由于负责保持维度不变量,更容易出错
YMMV,仅为了完整性:
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& backing = *seg.find_or_construct<Vector<double> >("my_backing")
(rows*cols, seg.get_segment_manager());
// ensure enough backing storage
backing.resize(rows*cols); // previous runs might have required less
backing.shrink_to_fit(); // optional: might not be optimal
boost::multi_array_ref<double, 2> data(
backing.data(),
boost::extents[rows][cols]);
fmt::print("shape: {} num_elements(): {} free in segment: {}\n",
std::vector(data.shape(), data.shape()+2),
data.num_elements(),
seg.get_free_memory()
);
std::iota(data.origin(), data.origin() + data.num_elements(), 1);
fmt::print("{}\n", fmt::join(data, "\n"));
}
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
template <typename T>
using Matrix = Vector<Vector<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& nested = *seg.find_or_construct<Matrix<double> >("manual_nested_vectors")
(seg.get_segment_manager());
// ensure enough nested storage
nested.clear();
nested.shrink_to_fit();
nested.assign(rows, Vector<double>(cols, seg.get_segment_manager())); // not very efficient
fmt::print("shape: {}x{} total elements: {} free in segment: {}\n",
rows, cols,
rows*cols,
seg.get_free_memory()
);
size_t base = 1;
for(auto& row : nested) {
std::iota(row.begin(), row.end(), base);
base += cols;
}
fmt::print("{}\n", fmt::join(nested, "\n"));
}
#如果定义不在线
#包括
#否则
#包括
#恩迪夫
#包括
#包括
//调试、演示输出:
#包括
#包括
静态std::mt19937 prng{std::random_设备{}()};
名称空间bip=boost::进程间;
命名空间bma=boost::多数组类型;
名称空间{
#ifdef无SHM_在线
使用Segment=bip::managed_-mapped_文件;
#否则
使用段=bip::托管共享内存;
#恩迪夫
模板
使用Alloc=bip::分配器;
模板
使用Vector=boost::container::Vector;
模板
使用矩阵=向量;
}
int main(){
段seg(bip::打开或创建,“我的共享内存”,1024);
自动行=1+prng()%5;
自动cols=1+prng()%7;
自动嵌套=*分段查找或构造(“手动嵌套向量”)
(seg.get_segment_manager());
//确保有足够的嵌套存储
nested.clear();
嵌套。将_收缩到_拟合();
nested.assign(行、向量(cols、seg.get_segment_manager());//效率不高
fmt::print(“形状:{}x{}总元素:{}段中的空闲元素:{}\n”,
排,排,
行*列,
seg.get_free_memory()
);
基础尺寸=1;
用于(自动行:嵌套(&W){
std::iota(row.begin()、row.end()、base);
碱基+=cols;
}
fmt::print(“{}\n”,fmt::join(嵌套,“\n”);
}
同样,以交互方式(比较分配示意图;另外,请注意clear()
和shrink\u to\u fit()
的发布顺序):
也许您可以将
多\u数组
与boost::进程间::分配器
一起使用。这需要多\u数组
支持有状态分配器
如果没有,您可以按任何方式手动分配内存,并使用:
multi_array_ref是一种多维容器适配器。它在任何连续的元素块上提供多数组接口。multi_array_ref导出与multi_array相同的接口,但构造函数除外
正在尝试multi_数组
使用multi_array
会失败,因为它在内部不支持富指针(offset_ptr
而不是double*
)
因此,使用multi\u array\u ref
将符合以下顺序:
演示multi\u array\u ref
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& backing = *seg.find_or_construct<Vector<double> >("my_backing")
(rows*cols, seg.get_segment_manager());
// ensure enough backing storage
backing.resize(rows*cols); // previous runs might have required less
backing.shrink_to_fit(); // optional: might not be optimal
boost::multi_array_ref<double, 2> data(
backing.data(),
boost::extents[rows][cols]);
fmt::print("shape: {} num_elements(): {} free in segment: {}\n",
std::vector(data.shape(), data.shape()+2),
data.num_elements(),
seg.get_free_memory()
);
std::iota(data.origin(), data.origin() + data.num_elements(), 1);
fmt::print("{}\n", fmt::join(data, "\n"));
}
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
template <typename T>
using Matrix = Vector<Vector<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& nested = *seg.find_or_construct<Matrix<double> >("manual_nested_vectors")
(seg.get_segment_manager());
// ensure enough nested storage
nested.clear();
nested.shrink_to_fit();
nested.assign(rows, Vector<double>(cols, seg.get_segment_manager())); // not very efficient
fmt::print("shape: {}x{} total elements: {} free in segment: {}\n",
rows, cols,
rows*cols,
seg.get_free_memory()
);
size_t base = 1;
for(auto& row : nested) {
std::iota(row.begin(), row.end(), base);
base += cols;
}
fmt::print("{}\n", fmt::join(nested, "\n"));
}
或者,在后续运行中:
或者,使用嵌套向量
这会带来更多的碎片风险,索引功能不如Boost Multi-Array强大,而且由于负责保持维度不变量,更容易出错
YMMV,仅为了完整性:
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& backing = *seg.find_or_construct<Vector<double> >("my_backing")
(rows*cols, seg.get_segment_manager());
// ensure enough backing storage
backing.resize(rows*cols); // previous runs might have required less
backing.shrink_to_fit(); // optional: might not be optimal
boost::multi_array_ref<double, 2> data(
backing.data(),
boost::extents[rows][cols]);
fmt::print("shape: {} num_elements(): {} free in segment: {}\n",
std::vector(data.shape(), data.shape()+2),
data.num_elements(),
seg.get_free_memory()
);
std::iota(data.origin(), data.origin() + data.num_elements(), 1);
fmt::print("{}\n", fmt::join(data, "\n"));
}
#ifdef NO_SHM_ONLINE
#include <boost/interprocess/managed_mapped_file.hpp>
#else
#include <boost/interprocess/managed_shared_memory.hpp>
#endif
#include <boost/container/vector.hpp>
#include <boost/multi_array.hpp>
// debug, demo output:
#include <fmt/ranges.h>
#include <random>
static std::mt19937 prng { std::random_device{}() };
namespace bip = boost::interprocess;
namespace bma = boost::multi_array_types;
namespace {
#ifdef NO_SHM_ONLINE
using Segment = bip::managed_mapped_file;
#else
using Segment = bip::managed_shared_memory;
#endif
template <typename T>
using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename T>
using Vector = boost::container::vector<T, Alloc<T> >;
template <typename T>
using Matrix = Vector<Vector<T> >;
}
int main() {
Segment seg(bip::open_or_create, "my_shared_mem", 1024);
auto rows = 1 + prng()%5;
auto cols = 1 + prng()%7;
auto& nested = *seg.find_or_construct<Matrix<double> >("manual_nested_vectors")
(seg.get_segment_manager());
// ensure enough nested storage
nested.clear();
nested.shrink_to_fit();
nested.assign(rows, Vector<double>(cols, seg.get_segment_manager())); // not very efficient
fmt::print("shape: {}x{} total elements: {} free in segment: {}\n",
rows, cols,
rows*cols,
seg.get_free_memory()
);
size_t base = 1;
for(auto& row : nested) {
std::iota(row.begin(), row.end(), base);
base += cols;
}
fmt::print("{}\n", fmt::join(nested, "\n"));
}
#如果定义不在线
#包括
#否则
#包括
#恩迪夫
#包括
#包括
//调试、演示输出:
#包括
#包括
静态std::mt19937 prng{std::random_设备{}()};
名称空间bip=boost::进程间;
命名空间bma=boost::多数组类型;
名称空间{
#ifdef无SHM_在线
使用Segment=bip::managed_-mapped_文件;
#否则
使用段=bip::托管共享内存;
#恩迪夫
模板
使用Alloc=bip::分配器;
模板
使用Vector=boost::container::Vector;
模板
使用矩阵=向量;
}
int main(){
段seg(bip::打开或创建,“我的共享内存”,1024);
自动行=1+prng()%5;
自动cols=1+prng()%7;
自动嵌套=*分段查找或构造(“手动嵌套向量”)
(seg.get_segment_manager());
//确保有足够的嵌套存储
nested.clear();
嵌套。将_收缩到_拟合();
nested.assign(行、向量(cols、seg.get_segment_manager());//效率不高
fmt::print(“形状:{}x{}总元素:{}段中的空闲元素:{}\n”,
排,排,
行*列,
seg.get_free_memory()
);
基础尺寸=1;
用于(自动行:嵌套(&W){
std::iota(row.begin()、row.end()、base);
碱基+=cols;
}
fmt::print(“{}\n”,fmt::join(嵌套,“\n”);
}
同样,以交互方式(比较分配示意图;另外,请注意clear()
和shrink\u to\u fit()
的发布顺序):
为(推荐)添加了实时演示,并为(推荐)和添加了实时演示