前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Boost】Interprocess - 共享内存、文件映射介绍

【Boost】Interprocess - 共享内存、文件映射介绍

作者头像
王亚昌
发布2018-08-03 15:54:15
4.4K0
发布2018-08-03 15:54:15
举报
文章被收录于专栏:王亚昌的专栏王亚昌的专栏

一、用法介绍

      通过Interprocess,可以实现在共享内存、文件映射中保存vector、map等STL对象,并且可以使用自定义的类,官方文档介绍的也很详细了,下面是几个精简的示例。

  • 示例:基于文件映射的Map使用
代码语言:javascript
复制
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <functional>
#include <cstdlib> //std::system
#include <utility>
#include <stdio.h>
#include <stdlib.h>
#include <exception>
#include <sys/mman.h>
#include <sys/stat.h>        /*  For mode constants */
#include <fcntl.h>           /*  For O_* constants */
#include <string>

using namespace boost::interprocess;
using std::string;

class Item
{
    public:
    Item(){}
    ~Item(){}

    int id;
    int size;
    string name;
};

typedef int KeyType;
typedef Item MappedType;
typedef std::pair<const int, Item> ValueType;

typedef allocator<ValueType, managed_mapped_file::segment_manager> ShmemAllocator;

typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;

int main()
{
    try {
        // init
        managed_mapped_file segment(open_or_create, "SharedMemory", 65536);


        MyMap *mymap = segment.find<MyMap>("MyMap").first;
        if (mymap == NULL)
        {
            const ShmemAllocator alloc_inst (segment.get_segment_manager());

            mymap = segment.construct<MyMap>("MyMap") (std::less<int>(), alloc_inst);

        }

        Item v;
        for(int i = 0; i < 100; ++i){
            v.id = i;
            mymap->insert(std::pair<const int, Item>(i, (Item)v));
        }

        for (MyMap::iterator it = mymap->begin(); it != mymap->end(); it++) {
            printf("%d ", it->second.id);
        }
        printf("\n");

        //file_mapping::remove("SharedMemory");
    }
    catch (const std::exception & e) {
        printf("Exception:%s\n", e.what());
        //file_mapping::remove("SharedMemory");
    }

    return 0;

}

执行后可以看到当前目录下已创建了内存文件。

代码语言:javascript
复制
[root@SH-todo-1412181717 /home/derrywang/boost/boost_1_60_0/demo]# ./interprocess_map_file
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
[root@SH-todo-1412181717 /home/derrywang/boost/boost_1_60_0/demo]# ls -al SharedMemory           
-rw-r--r-- 1 root root 65536 Feb 17 18:54 SharedMemory
  • 示例:基于共享内存的Map使用
代码语言:javascript
复制
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <functional>
#include <cstdlib>
#include <utility>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <exception>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>  
#include <string>

using namespace boost::interprocess;
using std::string;

class Item
{
    public:
        Item(){}
        ~Item(){}

        int id;
        int size;
        string name;
};

typedef int KeyType;
typedef Item MappedType;
typedef std::pair<const int, Item> ValueType;

typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator;

typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;

int main()
{
    try {
        // init
        managed_shared_memory segment(create_only, "SharedMemory", 65536);

        const ShmemAllocator alloc_inst (segment.get_segment_manager());

        MyMap * mymap = segment.construct<MyMap>("MyMap") (std::less<int>(), alloc_inst);

        Item v;
        for(int i = 0; i < 100; ++i){
            v.id = i;
            mymap->insert(std::pair<const int, Item>(i, (Item)v));
        }

        for (MyMap::iterator it = mymap->begin(); it != mymap->end(); it++) {
            printf("%d ", it->second.id);
        }
        printf("\n");

        shared_memory_object::remove("SharedMemory");
    }
    catch (const std::exception & e) {
        printf("Exception:%s\n", e.what());
        shared_memory_object::remove("SharedMemory");
    }

    return 0;

}
  • 示例:基于共享内存的Vector使用
代码语言:javascript
复制
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <cstdlib> //std::system
#include <stdio.h>
#include <stdlib.h>
#include <exception>
#include <sys/mman.h>
#include <sys/stat.h>        /*  For mode constants */
#include <fcntl.h>           /*  For O_* constants */
#include <string>

using namespace boost::interprocess;
using std::string;

class Item
{
    public:
        Item(){}
        ~Item(){}

        int id;
        int size;
        string name;
};

typedef allocator<Item, managed_shared_memory::segment_manager>  ShmemAllocator;

typedef vector<Item, ShmemAllocator> MyVector;

int main()
{
    try {
        // init
        managed_shared_memory segment(create_only, "SharedMemory", 65536);
        const ShmemAllocator alloc_inst (segment.get_segment_manager());
        MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);

        // push_back
        Item v;
        for(int i = 0; i < 100; i++) {
            v.id = i;
            myvector->push_back(v);
            v.name = "hello";
        }

        // loop
        MyVector *myvector2 = segment.find<MyVector>("MyVector").first;
        printf("vector size:%d\n", myvector2->size());
        for (int j = 0; j < myvector2->size(); j++)
            printf("%d  ", (*myvector2)[j].id);

        printf("\n");

        shared_memory_object::remove("SharedMemory");
    }
    catch (const std::exception & e) {
        printf("Exception:%s\n", e.what());
        shared_memory_object::remove("SharedMemory");
    }

    return 0;

}

Makefile如下,因为interprocess库不依赖库,所以头文件只需要包含boost顶层目录即可,仅依赖系统库编辑时需要指定-lrt.

代码语言:javascript
复制
BIN = $(patsubst %.cpp,%,$(wildcard *.cpp))

INC = -I ../
LIB = -lrt

RED = \\e[1m\\e[31m
RESET = \\e[m
GREEN = \\e[1m\\e[32m

all:$(BIN)

%:%.cpp
        @echo -e "Make $(GREEN)$@$(RESET) begin......\c"
        g++ -g -pthread -o $@ $< $(INC) $(LIB)
        @echo -e $(RED)"ok."$(RESET)

clean:
        rm $(BIN) 
        @echo "make clean done."

二、生命周期说明

机制上和Linux系统是一致的,分为进程级(进程退出销毁)、内核级(系统重启销毁)、文件系统级(文件删除销毁),这里不再赘述,附上官方原文。

One of the biggest issues with interprocess communication mechanisms is the lifetime of the interprocess communication mechanism. It's important to know when an interprocess communication mechanism disappears from the system. InBoost.Interprocess, we can have 3 types of persistence:

  • Process-persistence: The mechanism lasts until all the processes that have opened the mechanism close it, exit or crash.
  • Kernel-persistence: The mechanism exists until the kernel of the operating system reboots or the mechanism is explicitly deleted.
  • Filesystem-persistence: The mechanism exists until the mechanism is explicitly deleted.

Some native POSIX and Windows IPC mechanisms have different persistence so it's difficult to achieve portability between Windows and POSIX native mechanisms.Boost.Interprocess classes have the following persistence:

Table 14.1. Boost.Interprocess Persistence Table

Mechanism

Persistence

Shared memory

Kernel or Filesystem

Memory mapped file

Filesystem

Process-shared mutex types

Process

Process-shared semaphore

Process

Process-shared condition

Process

File lock

Process

Message queue

Kernel or Filesystem

Named mutex

Kernel or Filesystem

Named semaphore

Kernel or Filesystem

Named condition

Kernel or Filesystem

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年02月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档