提高::集装箱的集装箱间不共享内存中拷贝 [英] boost::interprocess Containers of containers NOT in shared memory copy

查看:172
本文介绍了提高::集装箱的集装箱间不共享内存中拷贝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于一个previous问题<α

href=\"http://stackoverflow.com/questions/26217012/boostinterprocess-containers-of-containers-not-in-shared-memory\">boost::interprocess不共享内存容器的容器我能够在共享内存和堆上创建对象。
我现在想要的是一个模板深拷贝功能,可用的SHM堆之间复制具有独立的分配器的所有进程间的载体。

 的#include&LT;升压/间/集装箱/ vector.hpp&GT;
#包括LT&;升压/间/分配器/ allocator.hpp&GT;
#包括LT&;升压/间/ managed_shared_memory.hpp&GT;
#包括LT&;升压/范围/ algorithm.hpp&GT;
#包括LT&;&iostream的GT;
#包括LT&;&了cassert GT;模板&LT; typename的T&GT;
使用BoundShmemAllocator =的boost ::进程间::分配器&LT; T,提高::进程间:: managed_shared_memory :: segment_manager取代;类MYSTRUCT {
上市:
    MYSTRUCT(){};
    MYSTRUCT(int i)以:I(我){};
    INT I;
};模板&LT;模板&LT; typename的...&GT;类BoundShmemAllocator&GT;
使用MyStructVector =的boost ::进程间::矢量&lt; MYSTRUCT,BoundShmemAllocator&LT;&MYSTRUCT GT;取代;//变堆中使用:
使用HeapMyStructVector = MyStructVector&LT;的std ::分配器取代;
//变到共享内存中使用:
使用ShmemMyStructVector = MyStructVector&LT; BoundShmemAllocator取代;// ----&GT;问题如何我得到这个工作,还是没有办法?
//模板&LT; typename的T,模板&LT; typename的...&GT;类AllocatorSrc,模板&LT; typename的...&GT;类AllocatorDes&GT;
//无效复印件(升压::进程间::矢量&lt; T,AllocatorSrc&LT; T&GT;&GT;&放大器; SRC,升压::进程间::矢量&lt; T,AllocatorDes&LT; T&GT;&GT;&安培; DES){
无效复制(常量ShmemMyStructVector&放大器; SRC,HeapMyStructVector&安培; DES){
    des.resize(src.size());
    类型名的boost ::进程间::矢量&lt; T,AllocatorSrc&LT; T&GT; &GT; ::为const_iterator itSrc;
    类型名的boost ::进程间::矢量&lt; T,AllocatorDes&LT; T&GT; &GT; ::迭代器itDst;
    为(itSrc = src.begin(),itDst = des.begin();!itSrc = src.end(); itDst ++ itSrc ++){
      * itDst = * itSrc;
    }
}
//
////////////////////////////////////////////////// /////////////诠释主(){
    函数srand(时间(NULL));    //一个管理的共享内存,我们可以构造对象
    提高::进程间:: managed_shared_memory段=的boost ::进程间:: managed_shared_memory(升压::进程间:: open_or_create,MySharedMemory,65536);
    BoundShmemAllocator&LT; INT&GT;常量shmem_alloc(segment.get_segment_manager());    ShmemMyStructVector * SRC = segment.find_or_construct&LT; ShmemMyStructVector&GT; (MYSTRUCT)(shmem_alloc);
    用于(为size_t我= 0;我小于5;我++)src-&GT;的push_back(RAND());    //你可以有这样的事情工作:
    HeapMyStructVector德; //也是SHM下面的东西
    des.push_back(RAND());
    副本(* SRC,DES);
    性病::法院LT&;&LT; SHMEM:
    用于(为size_t我= 0; I&LT; src-&GT;大小();我++)的std ::法院LT&;&LT; I&LT;&LT; :&所述;&下; src-&gt;对于(ⅰ).I&所述;&下; (!I = src-&GT;大小() - 1,?\\ n);
    性病::法院LT&;&LT; 堆;
    用于(为size_t我= 0; I&LT; des.size();我++)的std ::法院LT&;&LT; I&LT;&LT; :&所述;&下; des.at(我)。我&LT;&LT; (!I = des.size() - 1,:\\ N);
    segment.destroy&LT; ShmemMyStructVector&GT; (MYSTRUCT);
}


解决方案

你为什么要推的参数类型推演这么难?

 模板&LT; typename的Src的,typename的目的地&GT;
无效副本(SRC常量和放大器; SRC,目的地&安培; DES){
    des.assign(src.begin(),src.end());
}

作品对我来说就像魅力: 住在Coliru

(上MSVC注意,我需要从 https://svn.boost.org补丁/ TRAC /升压/票/ 9369


要评论:

惯用的伎俩是在演绎一个函数模板,你专门为不同的参数,并派遣一个函数对象的实际的参数类型。

在这种情况下,我部分专门用于矢量情况下,仅

 命名空间的细节{
    模板&LT; typename的Src的,typename的目的地&GT;结构复印机;    模板&LT; typename的T,typename的A1,A2类型名称和GT;结构复印机&LT;
        类型名的boost ::进程间::矢量&lt; T,A1&gt;中
        类型名的boost ::进程间::矢量&lt; T,A2&GT; &GT;
    {
        模板&LT; typename的Src的,typename的目的地&GT;
        静态无效电话(SRC常量和放大器; SRC,目的地&安培; DES){
            des.assign(src.begin(),src.end());
        }
    };
}模板&LT; typename的Src的,typename的目的地&GT;
无效副本(SRC常量和放大器; SRC,目的地&安培; DES){
    细节::复印机&LT; Src的,目的地&GT; ::模板调用(SRC,DES);
}

Based on a previous question boost::interprocess Containers of containers NOT in shared memory I am able to create objects in the shared memory and on the heap. What I want now is a template deep copy function to copy between heap an shm usable with all interprocess vectors independent to the allocator.

#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" );
}

解决方案

Why are you pushing argument type deduction so hard?

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

Works like a charm for me: Live On Coliru

(Note on MSVC I needed the patch from https://svn.boost.org/trac/boost/ticket/9369)


To the comment:

The usual trick is to deduce the arguments in a function template, and dispatch to a function object which you specialize for different actual argument types.

In this case, I partially specialized for the vector case only:

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);
}

这篇关于提高::集装箱的集装箱间不共享内存中拷贝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆