2014-10-06 3 views
1

boost::interprocess Containers of containers 유형의 예제 데모 프로그램이 있습니다. 그러나 클래스를 내 프로세스 메모리 내에서 정상 클래스로 사용하는 것을 좋아합니다. 누군가가 현재 프로세스 메모리에서 초기화 된 클래스를 갖기 위해 인수를 취하지 않는 생성자를 작성할 수있게 도와 줄 수 있습니까?boost :: interprocess 공유 메모리가 아닌 컨테이너 컨테이너

#include <boost/interprocess/containers/vector.hpp> 
#include <boost/interprocess/allocators/allocator.hpp> 
#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/archive/xml_oarchive.hpp> 
#include <boost/archive/xml_iarchive.hpp> 
#include <shmfw/serialization/interprocess_vector.hpp> 
#include <stdlib.h>  /* srand, rand */ 
#include <time.h>  /* time */ 


using namespace boost::interprocess; 
//Alias an STL-like allocator of ints that allocates ints from the segment 
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator; 

//Alias a vector that uses the previous STL-like allocator 
typedef vector<int, ShmemAllocator> MyVector; 

typedef allocator<void, managed_shared_memory::segment_manager >       void_allocator; 

class MyStruct { 
public: 
    MyVector myVector; 
    //Since void_allocator is convertible to any other allocator<T>, we can simplify 
    //the initialization taking just one allocator for all inner containers. 
    MyStruct (const void_allocator &void_alloc) 
     : myVector (void_alloc) 
    {} 
    // Thats what I like to have  
    //MyStruct() 
    // : myVector (??) 
    //{} 
}; 

int main() { 

    // I would like to have something like that working and also the shm stuff below 
    // MyStruct x; 


    managed_shared_memory segment; 
    //A managed shared memory where we can construct objects 
    //associated with a c-string 
    try { 
     segment = managed_shared_memory(create_only, "MySharedMemory", 65536); 
    } catch (...){ 
     segment = managed_shared_memory(open_only, "MySharedMemory"); 
    } 

    //Initialize the STL-like allocator 
    const ShmemAllocator alloc_inst (segment.get_segment_manager()); 

    MyStruct *myStruct_src = segment.find_or_construct<MyStruct> ("MyStruct") (alloc_inst); 
    srand (time(NULL)); 
    myStruct_src->myVector.push_back (rand()); 

    MyStruct *myStruct_des = segment.find_or_construct<MyStruct> ("MyStruct") (alloc_inst); 

    for (size_t i = 0; i < myStruct_src->myVector.size(); i++) { 
     std::cout << i << ": " << myStruct_src->myVector[i] << " = " << myStruct_des->myVector[i] << std::endl; 
    if(myStruct_src->myVector[i] != myStruct_des->myVector[i]) { 
     std::cout << "Something went wrong!" << std::endl; 
    } 
    } 


    //segment.destroy<MyVector> ("MyVector"); 
    return 0; 
} 

답변

1

할당 자 유형을 변경하면 컨테이너가 변경됩니다 (예 : 컴파일 타임 템플릿 인스턴스화의 특성).

기술적으로 유형 지워진 할당 자 (예 : std::function 또는 boost::any_iterator)를 고안 할 수는 있지만 성능이 좋지 않을 수 있습니다. 또한 모든 할당자가 여전히 정적으로 알려진 모든 속성에서 일치해야 유연성을 줄일 수 있습니다.

실제로는 포함 된 컨테이너에 Allocator 유형의 MyStruct을 템플릿으로 템플릿 화하는 것이 좋습니다. 그리고 특히 생성자에서 이러한 할당을 :

// Variant to use on the heap: 
using HeapStruct = MyStruct<std::allocator>; 
// Variant to use in shared memory: 
using ShmemStruct = MyStruct<BoundShmemAllocator>; 

데모 프로그램 :

#include <boost/interprocess/containers/vector.hpp> 
#include <boost/interprocess/allocators/allocator.hpp> 
#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/range/algorithm.hpp> 
#include <iostream> 
#include <cassert> 

namespace bip = boost::interprocess; 
template <typename T> 
    using BoundShmemAllocator = bip::allocator<T, bip::managed_shared_memory::segment_manager>; 

/////////////////////////////////////////////////////////////// 
// Your MyStruct, templatized for an Allocator class template 

template <template<typename...> class Allocator> 
class MyStruct { 
public: 
    bip::vector<int, Allocator<int> > ints; 
    bip::vector<double, Allocator<double> > doubles; 

    MyStruct(const Allocator<void>& void_alloc = {}) 
     : ints(void_alloc), 
      doubles(void_alloc) 
    {} 
}; 

// Variant to use on the heap: 
using HeapStruct = MyStruct<std::allocator>; 
// Variant to use in shared memory: 
using ShmemStruct = MyStruct<BoundShmemAllocator>; 

// 
/////////////////////////////////////////////////////////////// 

int main() { 
    srand(time(NULL)); 

    // You can have something like this working: 
    HeapStruct x; // and also the shm stuff below 
    std::generate_n(std::back_inserter(x.ints), 20, &std::rand); 
    std::generate_n(std::back_inserter(x.doubles), 20, &std::rand); 

    // A managed shared memory where we can construct objects 
    bip::managed_shared_memory segment = bip::managed_shared_memory(bip::open_or_create, "MySharedMemory", 65536); 
    BoundShmemAllocator<int> const shmem_alloc(segment.get_segment_manager()); 

    auto src = segment.find_or_construct<ShmemStruct>("MyStruct")(shmem_alloc); 
    src->ints.insert(src->ints.end(),  x.ints.begin(), x.ints.end()); 
    src->doubles.insert(src->doubles.end(), x.doubles.begin(), x.doubles.end()); 

    auto des = segment.find_or_construct<ShmemStruct>("MyStruct")(shmem_alloc); 

    std::cout << "-------------------------"; 
    boost::copy(src->ints, std::ostream_iterator<int>(std::cout << "\nsrc ints: ", "; ")); 
    boost::copy(des->ints, std::ostream_iterator<int>(std::cout << "\ndes ints: ", "; ")); 
    std::cout << "\n-------------------------"; 
    boost::copy(src->doubles, std::ostream_iterator<double>(std::cout << "\nsrc doubles: ", "; ")); 
    boost::copy(des->doubles, std::ostream_iterator<double>(std::cout << "\ndes doubles: ", "; ")); 

    assert(src->ints.size() == des->ints.size()); 
    assert(src->doubles.size() == des->doubles.size()); 
    assert(boost::mismatch(src->ints, des->ints) == std::make_pair(src->ints.end(), des->ints.end())); 
    assert(boost::mismatch(src->doubles, des->doubles) == std::make_pair(src->doubles.end(), des->doubles.end())); 

    segment.destroy<ShmemStruct>("MyStruct"); 
} 
+0

다양한 솔루션을, 감사 – Max

+0

을 사람이 scoped_allocator로이 답변을 결합하는 방법을 알고 있나요? -> 질문은 http://stackoverflow.com/q/28608185/1358042에 자세히 설명되어 있습니다. 감사합니다. – Max

관련 문제