boost共享内存中的动态二维阵列创建

boost共享内存中的动态二维阵列创建,boost,shared-memory,Boost,Shared Memory,我想使用boost在共享内存中存储一个二维数组。 我不知道这个数组在编译时的大小,只知道在运行时 实现这一目标的最佳方式是什么 有些代码会很受欢迎也许您可以将多数组与boost::interprocess::allocator一起使用。这需要多\u数组支持有状态分配器 如果没有,您可以按任何方式手动分配内存,并使用: multi_array_ref是一种多维容器适配器。它在任何连续的元素块上提供多数组接口。multi_array_ref导出与multi_array相同的接口,但构造函数除外 正在

我想使用boost在共享内存中存储一个二维数组。 我不知道这个数组在编译时的大小,只知道在运行时

实现这一目标的最佳方式是什么


有些代码会很受欢迎

也许您可以将
多数组
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()
的发布顺序):

为(推荐)添加了实时演示,并为(推荐)和添加了实时演示