专栏首页王亚昌的专栏【Boost】Interprocess - 共享内存、文件映射介绍

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

一、用法介绍

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

  • 示例:基于文件映射的Map使用
#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;

}

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

[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使用
#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使用
#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.

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 对数据操作封装的一点心得

    在对数据进行操作时,可能需要读写name,于是我们写了一个接口,这个接口会实时更新缓存

    王亚昌
  • 分布式消息队列浅析

    一个优秀的分布式消息队列,个人分析应该具备以下的能力:高吞吐、低时延(因场景而异),传输透明,伸缩性强,有冗灾能力,一致性顺序投递,同步+异步的发送方式,完善的...

    王亚昌
  • 分布式消息队列浅析

    队列作为一种比较抽象的数据结构,在程序世界中被广泛的应用,而实现方式和形态也各式各样,有使用进程内堆栈实现的,如stl库中的queue;有基于管道、Shmem实...

    王亚昌
  • qsc oj 22 哗啦啦村的刁难(3)(随机数,神题)

    哗啦啦村的刁难(3) 发布时间: 2017年2月28日 20:00   最后更新: 2017年2月28日 20:01   时间限制: 1000ms   内存限制...

    Angel_Kitty
  • 蓝桥杯-2019第十届蓝桥杯B组C++数的分解

    把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺序被视为同一...

    Debug客栈
  • 哈理工新生赛

    最近ACM协会的同学总是利用休息的时间来玩LOL,而且一不小心就玩过头,就耽误了培训时间,这让会长很头疼。玩LOL的同学都知道LOL的全英文名是League o...

    AngelNH
  • 【Bazinga HDU - 5510 】【考察strstr()的使用】【贪心】

    1.题目大致说的是让你输出符合这种条件(在所给的字符串中至少有一个不是它的子串)的字符串对应的label,若没有输出-1; 2.判断子串可以用string.h...

    _DIY
  • 天梯赛初赛 进阶题 题解

    L2-009 抢红包 题目链接: https://www.patest.cn/contests/gplt/L2-009 简单题,结构体排序 #include...

    ShenduCC
  • 爬虫课程(九)|豆瓣:Scrapy中items设计及如何把item传给Item Pipeline

    黄小怪
  • Linux下socket双向通信

    linux下的socket与windows下的类似,就是少一个初始化的过程。 服务端 客户端 1 创建socke...

    李海彬

扫码关注云+社区

领取腾讯云代金券