【问题标题】:how to create multiple containers in boost shared memory?如何在 boost 共享内存中创建多个容器?
【发布时间】:2015-04-13 05:47:32
【问题描述】:

可以在共享内存中构造多个对象,如下例所示:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <functional>
#include <iostream>

using namespace boost::interprocess;

void construct_objects(managed_shared_memory &managed_shm)
{
  managed_shm.construct<int>("Integer")(99);
  managed_shm.construct<float>("Float")(3.14);
}

int main()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{open_or_create, "Boost", 1024};
  auto atomic_construct = std::bind(construct_objects,
    std::ref(managed_shm));
  managed_shm.atomic_func(atomic_construct);
  std::cout << *managed_shm.find<int>("Integer").first << '\n';
  std::cout << *managed_shm.find<float>("Float").first << '\n';
}

但是当我尝试创建两个向量或一个向量和一个列表时,我遇到了内存分配问题。有没有办法在 Boost 的单个共享内存中创建多个容器? 我查看了managed_memory_impl.hpp,但也没有太大帮助。 这是我的代码(你必须将它与 lib pthread 和 librt 链接):

#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <cstddef>
#include <cassert>
#include <utility>
#include <iostream>

typedef boost::interprocess::allocator<int, boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator; //Define an STL compatible allocator of ints that allocates from the managed_shared_memory. This allocator will allow placing containers in the segment 
typedef boost::interprocess::vector<int, ShmemAllocator> MyVector; //Alias a vector that uses the previous STL-like allocator so that allocates its values from the segment

typedef boost::interprocess::allocator<int, boost::interprocess::managed_shared_memory::segment_manager> ShmemListAllocator;
typedef boost::interprocess::list<int, ShmemListAllocator> MyList;    

int main(int argc, char *argv[])
{
      //Construct managed shared memory
      boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only, "MySharedMemory", 65536);

      //const ShmemAllocator alloc_inst(segment.get_segment_manager());
      MyVector *instance = segment.construct<MyVector>("MyType instance")(segment.get_segment_manager());
      MyVector *instance2 = segment.construct<MyVector>("MyType instance")(segment.get_segment_manager());
      MyList *instance3 = segment.construct<MyList>("MyList instance")(segment.get_segment_manager());
   return 0;
}//main

【问题讨论】:

  • 您应该比“我遇到内存分配问题”更具体。我们现在不得不猜测
  • 对不起,我的意思是 instance2 和 instance3 没有被创建,因为 getsegmentmanager 获得了与 instance1 相同的段管理器,这会引发错误
  • 这完全是错误的逻辑。段经理管理段。它们可以(显然)包含多个对象。 (不然怎么会有名字)
  • 这就是我的想法。请运行代码并查看。它崩溃了
  • 我不明白你为什么看起来如此恼火/不耐烦。看看我的 Boost Interprocess 答案。我真的不需要运行这个。无论如何,我已经用实时、运行、示例更新了我的答案。如果仍然无法正常工作,我们应该开始查看所涉及的环境

标签: boost shared-memory


【解决方案1】:

您应该使用唯一的名称,或者您可以使用索引(“数组”)构造样式。

请参阅Object construction function family 的文档:

//!Allocates and constructs an array of objects of type MyType (throwing version)
//!Each object receives the same parameters (par1, par2, ...)
MyType *ptr = managed_memory_segment.construct<MyType>("Name")[count](par1, par2...);

//!Tries to find a previously created object. If not present, allocates and
//!constructs an array of objects of type MyType (throwing version). Each object
//!receives the same parameters (par1, par2, ...)
MyType *ptr = managed_memory_segment.find_or_construct<MyType>("Name")[count](par1, par2...);

//!Allocates and constructs an array of objects of type MyType (throwing version)
//!Each object receives parameters returned with the expression (*it1++, *it2++,... )
MyType *ptr = managed_memory_segment.construct_it<MyType>("Name")[count](it1, it2...);

可能还有更多。寻找[count]

(为简单起见,我建议使用唯一名称)

更新

对于 cmets,这就是我所说的“唯一名称”的意思。我已经测试过了,它运行良好:

Live1 On Coliru

#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>

typedef boost::interprocess::allocator<int, boost::interprocess::managed_shared_memory::segment_manager>
    ShmemAllocator; // Define an STL compatible allocator of ints that allocates from the managed_shared_memory. This allocator
                    // will allow placing containers in the segment
typedef boost::interprocess::vector<int, ShmemAllocator> MyVector; // Alias a vector that uses the previous STL-like allocator so
                                                                   // that allocates its values from the segment

typedef boost::interprocess::allocator<int, boost::interprocess::managed_shared_memory::segment_manager> ShmemListAllocator;
typedef boost::interprocess::list<int, ShmemListAllocator> MyList;

int main()
{
    // Construct managed shared memory
    std::remove("/dev/shm/MySharedMemory");
    boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only, "MySharedMemory", 65536);

    // const ShmemAllocator alloc_inst(segment.get_segment_manager());
    MyVector *instance  = segment.construct<MyVector>("MyType instance 1")(segment.get_segment_manager());
    MyVector *instance2 = segment.construct<MyVector>("MyType instance 2")(segment.get_segment_manager());
    MyList   *instance3 = segment.construct<MyList>  ("MyList instance")(segment.get_segment_manager());

    assert(instance);
    assert(instance2);
    assert(instance3);

    assert(!std::equal_to<void*>()(instance,  instance2));
    assert(!std::equal_to<void*>()(instance,  instance3));
    assert(!std::equal_to<void*>()(instance2, instance3));
}

1 当然,Coliru 不支持 SHM。但是,使用映射文件的相同示例:Live On Coliru

【讨论】:

  • 谢谢sehe,但我发布的原因是因为我想创建容器,就像我在代码中所做的那样,虽然我已经阅读了 boost 文档,但我无法理解如何替换这些参数通过getsegmentmanager的返回值
  • 您的看法具体有什么不同?
  • 我已经更新了我的答案,使用实时、运行、示例来证明我的意思。我希望你能明白我的意思。
  • 啊,是命名导致了错误!非常感谢你 :-) 现在可以使用了。
  • @Nav 我想这一直是我回答的第一行 :) 很高兴它现在可以工作了
猜你喜欢
  • 2014-11-30
  • 1970-01-01
  • 2015-04-20
  • 2019-12-17
  • 1970-01-01
  • 2012-02-04
  • 2012-01-28
  • 1970-01-01
相关资源
最近更新 更多