为什么 boost::interprocess::managed_shared_memory 在构造时抛出 boost::interprocess_exception?
Why does boost::interprocess::managed_shared_memory throw a boost::interprocess_exception upon construction?
在下面的代码中,我试图初始化一个 managed_shared_memory 对象。调用构造函数时,我看到以下错误消息 -
在抛出 'boost::interprocess::interprocess_exception' 的实例后调用终止
什么():boost::interprocess_exception::library_error
中止
为什么会抛出这个异常?
我 运行 在 ubuntu 16.04 linux OS 上使用 g++ 9.3.0 编译程序。提升版本 1.58.0
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;
};
它中止,因为段管理器控制块的大小不足。
sizeof(test_obj)
只有 56 个字节(在我的系统上)。
如果您给该段 10 KiB,它会报告有效使用了 224 个字节:
#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";
}
版画
56
10016
Effectively used:224
总结
也许您不想要具有动态分配功能的段管理器。在这种情况下,请改为查看 shared_memory_object
。
奖励:使用映射区域的示例
要在固定大小的区域中存储“哑对象”,您不需要段管理器。您可以在 shared_memory_object
(或 file_mapping
)上使用 mapped_region
。
这是另一个示例 Live On Coliru
#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;
}
打印,当 运行 连续 4 次时:
x:0
x:167
x:0
x:167
在下面的代码中,我试图初始化一个 managed_shared_memory 对象。调用构造函数时,我看到以下错误消息 -
在抛出 'boost::interprocess::interprocess_exception' 的实例后调用终止 什么():boost::interprocess_exception::library_error 中止
为什么会抛出这个异常? 我 运行 在 ubuntu 16.04 linux OS 上使用 g++ 9.3.0 编译程序。提升版本 1.58.0
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;
};
它中止,因为段管理器控制块的大小不足。
sizeof(test_obj)
只有 56 个字节(在我的系统上)。
如果您给该段 10 KiB,它会报告有效使用了 224 个字节:
#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";
}
版画
56
10016
Effectively used:224
总结
也许您不想要具有动态分配功能的段管理器。在这种情况下,请改为查看 shared_memory_object
。
奖励:使用映射区域的示例
要在固定大小的区域中存储“哑对象”,您不需要段管理器。您可以在 shared_memory_object
(或 file_mapping
)上使用 mapped_region
。
这是另一个示例 Live On Coliru
#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;
}
打印,当 运行 连续 4 次时:
x:0
x:167
x:0
x:167