一、用法介绍
通过Interprocess,可以实现在共享内存、文件映射中保存vector、map等STL对象,并且可以使用自定义的类,官方文档介绍的也很详细了,下面是几个精简的示例。
#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_file0 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复制
#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;}复制
#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 = -lrtRED = \\e[1m\\e[31mRESET = \\e[mGREEN = \\e[1m\\e[32mall:$(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:
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 |
#include <iostream>#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <boost/interprocess/containers/string.hpp>using namespace std;int main() { //boost::interprocess::shared_memory_object类是按照单个字节的方式读写共享内存,用起来不方便 boost::interprocess::shared_memory_object::remove("Highscore"); boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "Highscore", 1024);//分配1024字节 //boost不能直接写入stl中的vector, map,string等,必须在boost::interprocess提供的另外一个分配器定义对应的数据类型,不是c++缺省的分配器 //创建一个分配器,内部使用的是"托管共享内存段管理器",段管理器负责管理位于共享内存内部的内存 typedef boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager> CharAllocator; //使用新建的分配器定义string对应的数据类型基于boost::interprocess::basic_stirng,经过分配器访问段管理器 typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> string; //find_or_construct创建string实例需要知道那个段管理器被访问,所以段管理器指针作为构造函数的第二个指针 string* str = managed_shm.find_or_construct<string>("String")("Hello!", managed_shm.get_segment_manager()); str->insert(5, " world"); cout << *str << endl; getchar(); return 0; }