circle_buffer和managed_mapped_file分段错误 [英] circular_buffer and managed_mapped_file segmentation fault

查看:63
本文介绍了circle_buffer和managed_mapped_file分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用boost 1.73.0,并且正在尝试将circular_buffer和manage_mapped_file一起使用,以将字符串存储在持久化在磁盘上的循环缓冲区中.

I am using boost 1.73.0, and am trying to use circular_buffer together with manage_mapped_file to store strings in a circular buffer persisted on disk.

我执行以下操作来创建/打开"circular_buffer":

I do the following to create/open the circular_buffer:

boost::interprocess::managed_mapped_file mmf(boost::interprocess::open_or_create, "./circ_buffer.bin", 10u << 10);
typedef boost::interprocess::allocator<std::string, boost::interprocess::managed_mapped_file::segment_manager> string_allocator;
typedef boost::circular_buffer<std::string, string_allocator> circ_buf;
circ_buf* instance = mmf.find_or_construct<circ_buf>("some_name")(10, mmf.get_segment_manager());

这很好用,我可以像这样将字符串放入circle_buffer中:

This works well and I can put strings in the circular_buffer like this:

for(int idx = 0 ; idx < 15; idx++) {
    std::string v = "mystring1-" + std::to_string(idx);
    instance->push_back(v);
}

看着原始文件(即使它是二进制文件),我也确实在其中看到了字符串,因此,似乎circular_buffer确实存在.

Looking at the raw file (even though it is binary) I dosee the strings inthere, so it seems like the circular_buffer was indeed persisted.

但是,如果我尝试按另一个代码片段所示的方式在另一个进程中加载​​circle_buffer,并像这样读取第一个元素:

But, if I try to load the circular_buffer in another process as shown in the first code snippet and read the first element like this:

instance->front()

我遇到了细分错误.我知道最后我需要围绕内存访问进行同步,但是在上面的示例中这应该不是问题,因为在给定的时间内只有一个进程正在访问文件.

I get a segmentation fault. I know that in the end I will need sychronization around memory access, but this should not be the problem in the example above as only one process is accessing the file a any given time.

有趣的是,如果我在分配器中用char替换std :: string,我不会遇到分段错误.我在做什么错了?

The funny thing is that if I substitute std::string with char in the allocator I do not get the segmentation fault. What am I doing wrong?

Rgds克劳斯

推荐答案

boost::interprocess::managed_mapped_file mmf(boost::interprocess::open_or_create, "./circ_buffer.bin", 10u << 10);
typedef boost::interprocess::allocator<std::string, boost::interprocess::managed_mapped_file::segment_manager> string_allocator;
typedef boost::circular_buffer<std::string, string_allocator> circ_buf;
circ_buf* instance = mmf.find_or_construct<circ_buf>("some_name")(10, mmf.get_segment_manager());

您在共享内存中分配 string 对象.但是, string 本身会进行分配,而您从未告诉过它使用共享内存分配器.

You allocate the string objects in shared memory. However, string itself allocates, and you never told it to use the shared-memory allocator.

您可能会在数据中看到字符串的原因是由于

The reason you may be seeing short strings inside the data is because of SSO

在Coliru上直播

Live On Coliru

#include <boost/circular_buffer.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <iostream>
#include <iomanip>
namespace bip = boost::interprocess;

namespace Shared {
    using Mem = bip::managed_mapped_file;
    using Segment = Mem::segment_manager;

    template <typename T> using Alloc = bip::allocator<T, Segment>;
    template <typename T> using Buffer = boost::circular_buffer<T, Alloc<T> >;

    using String = bip::basic_string<char, std::char_traits<char>, Alloc<char> >;
    using StringBuf = Buffer<String>;
}

int main() {
    using namespace Shared;
    Mem mmf(bip::open_or_create, "./circ_buffer.bin", 10U << 10);

    auto& buf = *mmf.find_or_construct<StringBuf>("some_name")(10, mmf.get_segment_manager());

    for (auto& s : buf) {
        std::cout << "Existing " << std::quoted(std::string_view(s)) << "\n";
    }

    for (char const* init : {"foo", "bar", 
            "some pretty long string to make sure we don't fall into SSO territory"
            "some pretty long string to make sure we don't fall into SSO territory"
            "some pretty long string to make sure we don't fall into SSO territory"
            "some pretty long string to make sure we don't fall into SSO territory"
        })
    {
        buf.push_back(String(init, mmf.get_segment_manager()));
    }
}

在第二次运行时打印:

Existing "foo"
Existing "bar"
Existing "some pretty long string to make sure we don't fall into SSO territorysome pretty long string to make sure we don't fall into SSO territorysome pretty long string to make sure we don't fall into SSO territorysome pretty long string to make sure we don't fall into SSO territory"

这篇关于circle_buffer和managed_mapped_file分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆