如前所述,容器开发者可能需要更改他们的实现以使其与 Boost.Interprocess 兼容,因为实现通常会忽略带有智能指针的分配器。幸运的是,一些 Boost 容器与 Interprocess 兼容。
Boost.Unordered 容器与 Interprocess 兼容,因此程序员可以将哈希容器存储在共享内存和内存映射文件中。这是一个在共享内存中存储 unordered_map
的小例子
#include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/allocators/allocator.hpp> #include <boost/unordered_map.hpp> //boost::unordered_map #include <functional> //std::equal_to #include <boost/container_hash/hash.hpp> //boost::hash int main () { using namespace boost::interprocess; //Remove shared memory on construction and destruction struct shm_remove { shm_remove() { shared_memory_object::remove("MyName"); } ~shm_remove(){ shared_memory_object::remove("MyName"); } } remover; //Create shared memory managed_shared_memory segment(create_only, "MyName", 65536); //Note that unordered_map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>, //so the allocator must allocate that pair. typedef int KeyType; typedef float MappedType; typedef std::pair<const int, float> ValueType; //Typedef the allocator typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator; //Alias an unordered_map of ints that uses the previous STL-like allocator. typedef boost::unordered_map < KeyType , MappedType , boost::hash<KeyType> ,std::equal_to<KeyType> , ShmemAllocator> MyHashMap; //Construct a shared memory hash map. //Note that the first parameter is the initial bucket count and //after that, the hash function, the equality function and the allocator MyHashMap *myhashmap = segment.construct<MyHashMap>("MyHashMap") //object name ( 3u, boost::hash<int>(), std::equal_to<int>() // , segment.get_allocator<ValueType>()); //allocator instance //Insert data in the hash map for(std::size_t i = 0; i < 100u; ++i){ myhashmap->insert(ValueType((int)i, (float)i)); } return 0; }
广泛使用的 Boost.MultiIndex 库与 Boost.Interprocess 兼容,因此我们可以在共享内存中构建相当不错的数据库。在共享内存中构建数据库比在普通内存中更困难一些,通常是因为这些数据库包含字符串,而这些字符串需要放置在共享内存中。共享内存字符串在其构造函数中需要分配器,因此这通常使对象插入变得更加复杂。
这是一个展示如何将多索引容器放入共享内存的例子
#include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/allocators/allocator.hpp> #include <boost/container/string.hpp> #include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> using namespace boost::interprocess; namespace bmi = boost::multi_index; typedef managed_shared_memory::allocator<char>::type char_allocator; typedef boost::container::basic_string<char, std::char_traits<char>, char_allocator>shm_string; //Data to insert in shared memory struct employee { int id; int age; shm_string name; employee( int id_ , int age_ , const char *name_ , const char_allocator &a) : id(id_), age(age_), name(name_, a) {} }; //Tags struct id{}; struct age{}; struct name{}; // Define a multi_index_container of employees with following indices: // - a unique index sorted by employee::int, // - a non-unique index sorted by employee::name, // - a non-unique index sorted by employee::age. typedef bmi::multi_index_container< employee, bmi::indexed_by< bmi::ordered_unique <bmi::tag<id>, bmi::member<employee,int,&employee::id> >, bmi::ordered_non_unique< bmi::tag<name>, bmi::member<employee,shm_string,&employee::name> >, bmi::ordered_non_unique <bmi::tag<age>, bmi::member<employee,int,&employee::age> > >, managed_shared_memory::allocator<employee>::type > employee_set; int main () { //Remove shared memory on construction and destruction struct shm_remove { shm_remove() { shared_memory_object::remove("MyName"); } ~shm_remove(){ shared_memory_object::remove("MyName"); } } remover; //Create shared memory managed_shared_memory segment(create_only,"MyName", 65536); //Construct the multi_index in shared memory employee_set *es = segment.construct<employee_set> ("My MultiIndex Container") //Container's name in shared memory ( employee_set::ctor_args_list() , segment.get_allocator<employee>()); //Ctor parameters //Now insert elements char_allocator ca(segment.get_allocator<char>()); es->insert(employee(0,31, "Joe", ca)); es->insert(employee(1,27, "Robert", ca)); es->insert(employee(2,40, "John", ca)); return 0; }
程序员可以将 Boost.CircularBuffer 容器放置在共享内存中,前提是他们使用宏定义 BOOST_CB_DISABLE_DEBUG
或更通用的 NDEBUG
禁用调试工具。原因是这些调试工具仅与原始指针兼容。