动态插入数据的共享内存

背景:有时候我们有这样的需求,想往共享内存里面存入我们定义的数据类型,数据类型可能是类的对象,结构体,或者普通的string,int等基本类型。通过共享内存我们可以进行多进程之间的通信(所谓的通信简单理解为两个进程之间交流共享内存中的数据),也有的时候可能不是为了数据交流,是想利用共享内存的持久机制,即共享内存之中的数据不随着程序的重启或者core了而消失。基于这个需求,我设计了一套通用的代码,用于动态插入各种类型的数据。供大家参考。

原理:

共享内存有两种API。一种是 POSIX共享内存API( shm_open() 、 shm_unlink() ),另外一种是System V共享内存 API(shmget(),shmat(),shmdt(),shmctl())。前面一种相较后面一种更易于操作,也是linux为了简便用户操作而提供给程序员的一套API。

boost库基于posix API,封装了对于共享内存的创建与设置共享内存大小的接口。并且通过红黑树算法实现对自定义数据类型的快速插入与查找,所以程序员的我们不必担心它的插入与查找效率。

基于响彻C++界的boost库的managed shared memory。这是一个媲美标准库的代码,可以直接操作。话不多说,直接上代码

#include 
#include   //boost::map
#include 
#include     // basic_string
#include 
#include 
#include    //std::equal_to
#include 
#include 
#include 
#include 
#include 

using namespace boost::interprocess;

// packet all interface for managed shared memory 
// 基于管理共享内存封装了一系列增删改查的接口
template
class SharedMemory {
    typedef managed_shared_memory::segment_manager                       segment_manager_t;  
    typedef allocator                           void_allocator;
    typedef allocator                           char_allocator;  
    typedef boost::container::basic_string, char_allocator>   char_string;  
    typedef std::pair ValueType;
    typedef allocator ShmemAllocator;
    typedef map, ShmemAllocator> SharedMap;
    

    public:
        // return SharedMemory type value
        // 返回当前类的实例
        static SharedMemory& instance();
        // create map container in managed shared memory
        // 创建一个有序map在共享内存上面
        void Create();
        // delete T type value by key
        // 根据键删除map上面的值
        void Destory();
        // insert T type value into map
        // 插入T类型的数据
        void insert(const char*  key,T* t);
        // find a T record by key
        // 插入T类型的数据
        T* find(const char* key);
    private:
        SharedMemory();
        ~SharedMemory(){delete m_segment;}
        
        managed_shared_memory* m_segment;
        std::size_t m_size;
        const char * m_sharedMemoryKey;
        const char * m_mapKey;
        void_allocator* m_voidalloc;
};


// 构造函数
template
inline SharedMemory::SharedMemory()
    : m_size(65536), m_sharedMemoryKey("Chinese"),m_mapKey("Shenzhen"){
}

// 共享内存类对象
template
inline SharedMemory& SharedMemory::instance() {
    static SharedMemory instance;
    return instance;
}

// 调用管理共享内存的managed_shared_memory类进行实例化,一定要自定义allocator
template
inline void SharedMemory::Create() {
    Destory();
    m_segment = new  managed_shared_memory(create_only, m_sharedMemoryKey, m_size);
    m_voidalloc =new  void_allocator(m_segment->get_segment_manager());
    m_segment->construct(m_mapKey)(std::less(),*m_voidalloc);
}

// 调用管理共享内存的remove接口
template
inline void SharedMemory::Destory() {
    ::shared_memory_object::remove(m_sharedMemoryKey);
}

// 调用管理共享内存的find的接口,再调用map的insert接口
template
inline void SharedMemory::insert(const char* key,T* t) {
    const char_string  key_object(key, *m_voidalloc);  
    SharedMap* mymap = m_segment->find(m_mapKey).first;
    mymap->insert(ValueType(key_object, *t));
}

// 调用管理共享内存的find的接口,再调用map的find接口
template
inline T* SharedMemory::find(const char* key) {
    const char_string  key_object(key, *m_voidalloc);  
    SharedMap* mymap = m_segment->find(m_mapKey).first;
    auto  it =  mymap->find(key_object);
    if ( it == (*mymap).end() )
    {
        std::cout << "not found " << key_object <<  std::endl;
    }
    return &(it->second);
}





class people{
    public:
        int m_age;
        bool m_gender;
        people(int age,bool gender) : m_age(age),m_gender(gender){};
};

int main()
{
    SharedMemory& test = SharedMemory::instance();
    test.Create();
    test.insert("pelple",new people(18,true));
    people* it= test.find("pelple");
    std::cout << "age is " << it->m_age << std::endl;
    return 0;
}


// g++ -g -O3 -Wall -std=c++11 -lpthread -lrt test_singleton_class_shared_memory.cpp -o test_singleton_class_shared_memory

上面我把这个定义成了一个模板,这样有利于存储各种类型数据

你可能感兴趣的:(c++,算法,c语言,中间件,开发语言)