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

how to create multiple containers in 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,但也没什么用。 这是我的代码(你必须 link 它与 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

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

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

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

更新

对于评论,这就是我 "unique name" 的意思。我已经测试过了,它工作正常:

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