boost :: interprocess scoped_allocator和不在共享内存中的容器的容器 [英] boost::interprocess scoped_allocator AND Containers of containers NOT in shared memory
问题描述
我在 boost :: interprocess中遇到类似的问题。容器不在共享内存中的容器和如何创建一个boost进程间进程向量的进程间容器,但这一次我喜欢使用我的类,它使用一个scoped_allocator,也在堆和共享内存。
现在我喜欢有两个,这是可能吗?
附加一个工作scoped_allocator的例子,但我不知道如何模板在这种情况下的类的分配器
提前感谢: - ) / p>
Markus
#include< boost / interprocess / managed_shared_memory.hpp> ;
#include< boost / container / scoped_allocator.hpp>
#include< boost / interprocess / allocators / allocator.hpp>
#include< boost / interprocess / containers / vector.hpp>
#include< boost / algorithm / string.hpp>
命名空间bi = boost :: interprocess;
namespace bc = boost :: container;
typedef bi :: managed_shared_memory :: segment_manager segment_manager_t;
typedef bc :: scoped_allocator_adaptor< bi :: allocator< void,segment_manager_t> > void_allocator;
class CheckList {
typedef void_allocator :: rebind< double> :: other double_allocator;
typedef bc :: vector< double,double_allocator> double_vector;
public:
double_vector values;
typedef void_allocator allocator_type;
//由于void_allocator可以转换为任何其他分配器< T> ;,我们可以简化
//初始化只需要一个分配器用于所有内部容器。
CheckList(const allocator_type& void_alloc)
:values(void_alloc){}
CheckList(CheckList const& other,const allocator_type& void_alloc)
:values (other.values,void_alloc){}
friend std :: ostream& operator<< (std :: ostream& os,const CheckList& o){
for(size_t i = 0; i< o.values.size(); i ++)os< (i>0≤,:)<< o.values [i];
return os;
}
};
类列表{
typedef void_allocator :: rebind< CheckList> :: other checklist_allocator;
typedef bc :: vector< CheckList,checklist_allocator> checklist_vector;
public:
列表(const void_allocator& void_alloc)
:checklists(void_alloc)
{}
checklist_vector checklists;
friend std :: ostream& operator<< (std :: ostream& os,const Lists& o){
for(size_t i = 0; i return os;
}
};
int main(int argc,char ** argv){
if(argc> 1& iequals(clear,argv [1])|| boost :: iequals(c,argv [1]))){
std :: cout< 移除共享存储器< std :: endl;
bi :: shared_memory_object :: remove(MySharedMemory);
}
//创建共享内存
bi :: managed_shared_memory段(bi :: open_or_create,MySharedMemory,16 * 1024 * 1024)
//可转换为任何分配器的分配器< T,segment_manager_t>类型
void_allocator alloc_inst(segment.get_segment_manager());
列表* lists = segment.find_or_construct<列表> (Lists)(alloc_inst);
if(lists-> checklists.size()!= 10){
std :: cout< 创建数据< std :: endl;
lists-> checklists.resize(10);
for(size_t i = 0; i< lists-> checklists.size(); i ++){
lists-> checklists [i] .values.resize(i + 1);
for(size_t j = 0; j< lists-> checklists [i] .values.size(); j ++){
lists-> checklists [i] .values [j] = j;
}
}
} else {
std :: cout< 数据存在< std :: endl;
}
std :: cout<< * lists<< std :: endl;
}
我不知道什么是挑战,超出...是让让分配器模板参数,并定义
命名空间Shared {
typedef bi :: managed_shared_memory :: segment_manager segment_manager_t;
typedef bc :: scoped_allocator_adaptor< bi :: allocator< void,segment_manager_t> > void_allocator;
using Lists = common :: Lists< void_allocator>
}
namespace Heap {
typedef std :: allocator< void> void_allocator;
using Lists = common :: Lists< void_allocator>
}
所以,我继续进行转换构造函数:
命名空间common {
template< typename Alloc>
class CheckList {
typedef typename Alloc :: template rebind< double> :: other double_allocator;
typedef bc :: vector< double,double_allocator> double_vector;
public:
double_vector values;
typedef Alloc allocator_type;
CheckList(const allocator_type& void_alloc = allocator_type()):values(void_alloc){}
template< typename Alloc2>
CheckList(CheckList< Alloc2> const& other,const allocator_type& void_alloc = allocator_type())
:values(void_alloc)
{
for(auto& v:other.values )values.emplace_back(v);
}
friend std :: ostream& <<<<<<(std :: ostream& os,const CheckList& o){
for(size_t i = 0; i< o.values.size(); i ++)
os< ; (i,:)< o.values [i];
return os;
}
};
template< typename Alloc>
class Lists {
typedef typename Alloc :: template rebind< CheckList< Alloc> > :: other checklist_allocator;
public:
typedef Alloc allocator_type;
typedef bc :: vector< CheckList< Alloc> ;, checklist_allocator> checklist_vector;
template< typename Alloc2>
列表& operator =(Lists< Alloc2> const& other){
for(auto& cl:other.checklists)checklists.emplace_back(cl);
return * this;
}
列表(const Alloc& void_alloc = allocator_type()):checklists(void_alloc){}
checklist_vector checklists;
friend std :: ostream& <<<<<(std :: ostream& os,const列表& o){
for(size_t i = 0; i< o.checklists.size(); i ++)
os< ; o.checklists [i]< '\\\
';
return os;
}
};
}
这意味着你现在可以有一个函数返回基于堆的集合它到共享内存版本相同:
Heap ::列表generate_local(){
Heap ::列表;
Heap :: Lists :: checklist_vector :: value_type v;
for(int i = 0; i <10; ++ i){
v.values.emplace_back(i + 1);
lists.checklists.push_back(v);
}
返回列表;
}
//以后:
列表& lists = * segment.find_or_construct< Lists>(Lists)(alloc_inst);
if(lists.checklists.size()!= 10){
std :: cout< 创建数据< std :: endl;
auto x = generate_local();
lists = std :: move(x);
}
I have a similar question as before in boost::interprocess Containers of containers NOT in shared memory and How to I create a boost interprocess vector of interprocess containers but this time I like to use my class, which uses a scoped_allocator, also on the heap and shared memory.
- The solution to my first question was to use a template class with an allocator type
- In my second previous question it turned out that using a scoped_allocator together with a container of containers within the shared memory makes live easier.
Now I like to have both, is this possible? Attached a example with a working scoped_allocator but I have no idea how to template in this case the allocator of the class?
Thanks in advance :-)
Markus
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/algorithm/string.hpp>
namespace bi = boost::interprocess;
namespace bc = boost::container;
typedef bi::managed_shared_memory::segment_manager segment_manager_t;
typedef bc::scoped_allocator_adaptor<bi::allocator<void, segment_manager_t> > void_allocator;
class CheckList {
typedef void_allocator::rebind<double>::other double_allocator;
typedef bc::vector<double, double_allocator> double_vector;
public:
double_vector values;
typedef void_allocator allocator_type;
//Since void_allocator is convertible to any other allocator<T>, we can simplify
//the initialization taking just one allocator for all inner containers.
CheckList ( const allocator_type &void_alloc )
: values ( void_alloc ) {}
CheckList ( CheckList const& other, const allocator_type &void_alloc )
: values ( other.values, void_alloc ) {}
friend std::ostream &operator << ( std::ostream &os, const CheckList &o ) {
for ( size_t i = 0; i < o.values.size(); i++ ) os << (i>0?", ":"") << o.values[i];
return os;
}
};
class Lists {
typedef void_allocator::rebind<CheckList>::other checklist_allocator;
typedef bc::vector<CheckList, checklist_allocator> checklist_vector;
public:
Lists ( const void_allocator &void_alloc )
: checklists ( void_alloc )
{}
checklist_vector checklists;
friend std::ostream &operator << ( std::ostream &os, const Lists &o ) {
for ( size_t i = 0; i < o.checklists.size(); i++ ) os << o.checklists[i] << std::endl;
return os;
}
};
int main ( int argc, char **argv ) {
if ( argc > 1 && (boost::iequals ( "clear", argv[1] ) || boost::iequals ( "c", argv[1] ) ) ) {
std::cout << "Remove shared memory" << std::endl;
bi::shared_memory_object::remove ( "MySharedMemory" );
}
//Create shared memory
bi::managed_shared_memory segment ( bi::open_or_create,"MySharedMemory", 16*1024*1024 );
//An allocator convertible to any allocator<T, segment_manager_t> type
void_allocator alloc_inst ( segment.get_segment_manager() );
Lists *lists = segment.find_or_construct<Lists> ( "Lists" ) ( alloc_inst );
if ( lists->checklists.size() != 10 ) {
std::cout << "Create Data" << std::endl;
lists->checklists.resize ( 10 );
for ( size_t i = 0; i < lists->checklists.size(); i++ ) {
lists->checklists[i].values.resize ( i+1 );
for ( size_t j = 0; j < lists->checklists[i].values.size(); j++ ) {
lists->checklists[i].values[j] = j;
}
}
} else {
std::cout << "Data Exists" << std::endl;
}
std::cout << *lists << std::endl;
}
Well. I'm not sure what was the challenge, beyond... yes let's make the allocator a template argument, and define
namespace Shared {
typedef bi::managed_shared_memory::segment_manager segment_manager_t;
typedef bc::scoped_allocator_adaptor<bi::allocator<void, segment_manager_t> > void_allocator;
using Lists = common::Lists<void_allocator>;
}
namespace Heap {
typedef std::allocator<void> void_allocator;
using Lists = common::Lists<void_allocator>;
}
So, I went ahead and actually made converting constructors:
namespace common {
template <typename Alloc>
class CheckList {
typedef typename Alloc::template rebind<double>::other double_allocator;
typedef bc::vector<double, double_allocator> double_vector;
public:
double_vector values;
typedef Alloc allocator_type;
CheckList(const allocator_type& void_alloc = allocator_type()) : values(void_alloc) {}
template <typename Alloc2>
CheckList(CheckList<Alloc2> const& other, const allocator_type& void_alloc = allocator_type())
: values(void_alloc)
{
for(auto& v : other.values) values.emplace_back(v);
}
friend std::ostream& operator<<(std::ostream& os, const CheckList& o) {
for (size_t i = 0; i < o.values.size(); i++)
os << (i?", ":"") << o.values[i];
return os;
}
};
template <typename Alloc>
class Lists {
typedef typename Alloc::template rebind<CheckList<Alloc> >::other checklist_allocator;
public:
typedef Alloc allocator_type;
typedef bc::vector<CheckList<Alloc>, checklist_allocator> checklist_vector;
template <typename Alloc2>
Lists& operator=(Lists<Alloc2> const& other) {
for(auto& cl : other.checklists) checklists.emplace_back(cl);
return *this;
}
Lists(const Alloc& void_alloc = allocator_type()) : checklists(void_alloc) {}
checklist_vector checklists;
friend std::ostream& operator<<(std::ostream& os, const Lists& o) {
for (size_t i = 0; i < o.checklists.size(); i++)
os << o.checklists[i] << '\n';
return os;
}
};
}
This means you can now have a function that returns heap-based collections and assign it to a shared-memory version of the same:
Heap::Lists generate_local() {
Heap::Lists lists;
Heap::Lists::checklist_vector::value_type v;
for (int i=0; i<10; ++i) {
v.values.emplace_back(i+1);
lists.checklists.push_back(v);
}
return lists;
}
// later:
Lists& lists = *segment.find_or_construct<Lists>("Lists")(alloc_inst);
if (lists.checklists.size() != 10) {
std::cout << "Create Data" << std::endl;
auto x = generate_local();
lists = std::move(x);
}
这篇关于boost :: interprocess scoped_allocator和不在共享内存中的容器的容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!