首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么boost::interprocess::managed_shared_memory要在构建时抛出一个boost::interprocess_exception?

为什么boost::interprocess::managed_shared_memory要在构建时抛出一个boost::interprocess_exception?
EN

Stack Overflow用户
提问于 2020-07-06 02:28:39
回答 1查看 1.4K关注 0票数 2

在下面的代码中,我试图初始化一个managed_shared_memory对象。当调用构造函数时,我看到下面的错误消息-

终止在抛出'boost::interprocess::interprocess_exception‘内容():boost::interprocess_exception::library_error中止的实例后调用

为什么要抛出这个异常?我正在一个ubuntu16.04LinuxOS上运行这个程序,它使用g++ 9.3.0编译了这个程序。Boost版本1.58.0

代码语言:javascript
复制
struct test_obj {
    size_t x;
    size_t y;
    uint8_t buf[32];
    bool is_valid;
};

class shm_wrapper {
        public:
            shm_wrapper() : m_shm(
                                boost::interprocess::open_or_create, 
                                "my_shm",
                                sizeof(test_obj) )
            {};
        private:
        boost::interprocess::managed_shared_memory m_shm;
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-06 15:30:13

由于大小不足以满足分段管理器控制块的要求,它将中止。

sizeof(test_obj)只有56个字节(在我的系统上)。

如果给出段10 KiB,它报告了有效使用的224个字节:

住在Coliru

代码语言:javascript
复制
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>

namespace bip = boost::interprocess;

#ifdef COLIRU
    using segment_type = bip::managed_mapped_file;
#else
    using segment_type = bip::managed_shared_memory;
#endif

static constexpr size_t SegmentSize = 10 * 1024;

struct test_obj {
    size_t x;
    size_t y;
    uint8_t buf[32];
    bool is_valid;
};

class shm_wrapper {
  public:
    shm_wrapper() : m_shm(bip::open_or_create, "my_shm", SegmentSize){};

    size_t free() const { return m_shm.get_free_memory(); }

  private:
    segment_type m_shm;
};

#include <iostream>
int main() {
    std::cout << sizeof(test_obj) << std::endl;
    shm_wrapper w;
    std::cout << w.free() << "\n";
    std::cout << "Effectively used:" << (SegmentSize - w.free()) << "\n";
}

打印

代码语言:javascript
复制
56
10016
Effectively used:224

摘要

也许您不想要一个具有动态分配功能的段管理器。在这种情况下,请看一下shared_memory_object

奖励:使用映射区域的示例

要在固定大小的区域中存储“哑对象”,不需要分段管理器。您可以在mapped_region (或file_mapping)上使用shared_memory_object

这是另一个示例住在Coliru

代码语言:javascript
复制
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
namespace bip = boost::interprocess;

struct test_obj {
    size_t x;
    size_t y;
    uint8_t buf[32];
    bool is_valid;
};

#ifdef COLIRU
    #include <fstream>
    using mapping_type = bip::file_mapping;
#else
    using mapping_type = bip::shared_memory_object;
#endif

template <typename T>
class shm_wrapper {
    static_assert(std::is_trivial_v<T>);
    static_assert(std::is_standard_layout_v<T>);

#ifdef COLIRU // file mappings require more work to cater for the storage
    struct backing_t { } backing;
    backing_t ensure_file(std::string name, size_t size) {
        std::filebuf fbuf;
        fbuf.open(name, std::ios::in | std::ios::out | std::ios::app | std::ios::binary);
        //set the size, sparsely
        fbuf.pubseekoff(size-1, std::ios_base::beg);
        fbuf.sputc(0);
        fbuf.close();
        return {};
    }
  public:
    shm_wrapper()
        : backing { ensure_file("my_shm", sizeof(T)) },
          m_mappable("my_shm", bip::read_write),
          m_reg(m_mappable, bip::read_write, 0, sizeof(T))
    { }
#else
  public:
    shm_wrapper()
        : m_mappable(bip::open_or_create, "my_shm", bip::read_write),
          m_reg(m_mappable, bip::read_write, 0, sizeof(T))
    {
        m_mappable.truncate(sizeof(T));
    }
#endif

    T& get()             { return *static_cast<T*>(m_reg.get_address()); }
    T const& get() const { return *static_cast<T const*>(m_reg.get_address()); }

    auto size() const { return m_reg.get_size(); } 
    auto flush()      { return m_reg.flush();    } 

  private:
    mapping_type m_mappable;
    bip::mapped_region m_reg;
};

int main() {
    shm_wrapper<test_obj> w;
    std::cout << "x:" << w.get().x << "\n";
    w.get().x ^= 0xa7;
    return w.flush()? 0 : 1;
}

打印,当连续运行4x时:

代码语言:javascript
复制
x:0
x:167
x:0
x:167
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62748438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档