如何在boost共享内存中创建多个容器?

时间:2015-04-13 05:47:32

标签: boost shared-memory

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

#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

1 个答案:

答案 0 :(得分:3)

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

请参阅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]

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

更新

对于评论,这里是我的意思&#34;唯一名称&#34;。我已经对它进行了测试,并且设计得很好:

<强> 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