boost :: interprocess不在共享内存副本中的容器容器

时间:2014-11-03 09:43:42

标签: boost vector copy shared-memory interprocess

基于前一个问题boost::interprocess Containers of containers NOT in shared memory,我能够在共享内存和堆上创建对象。 我现在想要的是一个模板深度复制函数,用于在堆之间复制一个shm,可用于独立于分配器的所有进程间向量。

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

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

class MyStruct {
public:
    MyStruct() {};
    MyStruct ( int i ) : i ( i ) {};
    int i;
};

template <template<typename...> class BoundShmemAllocator>
using MyStructVector = boost::interprocess::vector<MyStruct, BoundShmemAllocator<MyStruct> >;

// Variant to use on the heap:
using HeapMyStructVector  = MyStructVector<std::allocator>;
// Variant to use in shared memory:
using ShmemMyStructVector = MyStructVector<BoundShmemAllocator>;

// ----> Question how to I get this working, or way not?
//template <typename T, template<typename...> class AllocatorSrc, template<typename...> class AllocatorDes>
//void copy ( boost::interprocess::vector<T, AllocatorSrc<T> > &src, boost::interprocess::vector<T, AllocatorDes<T> > &des ) {
void copy ( const ShmemMyStructVector &src, HeapMyStructVector &des ) {
    des.resize ( src.size() );
    typename boost::interprocess::vector<T, AllocatorSrc<T> >::const_iterator itSrc;
    typename boost::interprocess::vector<T, AllocatorDes<T> >::iterator itDst;
    for(itSrc = src.begin(), itDst = des.begin(); itSrc != src.end(); itDst++, itSrc++){
      *itDst = *itSrc;
    }
}


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

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

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

    ShmemMyStructVector *src = segment.find_or_construct<ShmemMyStructVector> ( "MyStruct" ) ( shmem_alloc );   
    for ( size_t i = 0; i < 5; i++ )  src->push_back(rand());

    // You can have something like this working:
    HeapMyStructVector des; // and also the shm stuff below
    des.push_back(rand());


    copy(*src, des);
    std::cout << "Shmem: ";
    for ( size_t i = 0; i < src->size(); i++ ) std::cout << i << ": " << src->at(i).i << (i!=src->size()-1?", ":"\n");
    std::cout << "Heap: ";
    for ( size_t i = 0; i < des.size(); i++ ) std::cout << i << ": " << des.at(i).i << (i!=des.size()-1?", ":"\n");


    segment.destroy<ShmemMyStructVector> ( "MyStruct" );
}

1 个答案:

答案 0 :(得分:1)

为什么你这么努力地推动论证类型演绎?

template <typename Src, typename Dest>
void copy(Src const &src, Dest &des) {
    des.assign(src.begin(), src.end());
}

对我来说就像一个魅力: Live On Coliru

(关于MSVC的注意事项我需要来自https://svn.boost.org/trac/boost/ticket/9369的补丁)


评论:

通常的技巧是在函数模板中推导出参数,并调度到一个专门用于不同实际参数类型的函数对象。

在这种情况下,我只部分专门用于矢量案例:

namespace detail {
    template <typename Src, typename Dest> struct copier;

    template <typename T, typename A1, typename A2> struct copier<
        typename boost::interprocess::vector<T, A1>,
        typename boost::interprocess::vector<T, A2> >
    {
        template <typename Src, typename Dest>
        static void call(Src const &src, Dest &des) {
            des.assign(src.begin(), src.end());
        }
    };
}

template <typename Src, typename Dest>
void copy(Src const &src, Dest &des) {
    detail::copier<Src, Dest>::template call(src, des);
}