Boost.Interprocess使用手册翻译之二:快速指南 (Quick Guide for the Impatient)

二.快速指南(为急于想了解Boost.Interprocess的朋友)

使用共享内存做为一个匿名内存块池

创建命名共享内存对象

为共享内存使用一个偏移智能指针

在共享内存中创建容器(vector)

在共享内存中创建映射表(map)

 

使用共享内存做为一个匿名内存块池

你可以仅分配共享内存段的一部分,拷贝消息至那块缓冲区中,然后发送那部分共享内存的偏移量至另外一个进程即可。示例如下:

[cpp]  view plain copy
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <cstdlib> //std::system  
  3. #include <sstream>  
  4.    
  5. int main (int argc, char *argv[])  
  6. {  
  7.    using namespace boost::interprocess;  
  8.    if(argc == 1){  //Parent process  
  9.       //Remove shared memory on construction anddestruction  
  10.       struct shm_remove  
  11.       {  
  12.          shm_remove() {  shared_memory_object::remove("MySharedMemory");}  
  13.          ~shm_remove(){  shared_memory_object::remove("MySharedMemory"); }  
  14.       }remover;  
  15.    
  16.       //Create a managed shared memory segment  
  17.       managed_shared_memory segment(create_only,"MySharedMemory",65536);  
  18.    
  19.       //Allocate a portion of the segment (rawmemory)  
  20.       managed_shared_memory::size_type free_memory = segment.get_free_memory();  
  21.       void * shptr = segment.allocate(1024/*bytes toallocate*/);  
  22.    
  23.       //Check invariant  
  24.       if(free_memory <= segment.get_free_memory())  
  25.          return 1;  
  26.    
  27.       //An handle from the base address canidentify any byte of the shared  
  28.       //memory segment even if it is mapped indifferent base addresses  
  29.       managed_shared_memory::handle_t handle = segment.get_handle_from_address(shptr);  
  30.       std::stringstream s;  
  31.       s<< argv[0]<< " "<< handle;  
  32.       s<< std::ends;  
  33.       //Launch child process  
  34.       if(0 != std::system(s.str().c_str()))  
  35.          return 1;  
  36.       //Check memory has been freed  
  37.       if(free_memory != segment.get_free_memory())  
  38.          return 1;  
  39.    }  
  40.    else{  
  41.       //Open managed segment  
  42.       managed_shared_memory segment(open_only,"MySharedMemory");  
  43.    
  44.       //An handle from the base address canidentify any byte of the shared  
  45.       //memory segment even if it is mapped indifferent base addresses  
  46.       managed_shared_memory::handle_t handle = 0;  
  47.    
  48.       //Obtain handle value  
  49.       std::stringstream s; s<< argv[1];s >> handle;  
  50.    
  51.       //Get buffer local address from handle  
  52.       void *msg = segment.get_address_from_handle(handle);  
  53.    
  54.       //Deallocate previously allocated memory  
  55.       segment.deallocate(msg);  
  56.    }  
  57.    return 0;  
  58. }  

 创建命名共享内存对象

你可以在共享内存段中创建对象,给它们string类型的名字以便其他进程能够找到它们,使用它们,并且当对象不再使用时从内存段中删除它们。示例如下:

  
  
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <cstdlib> //std::system  
  3. #include <cstddef>  
  4. #include <cassert>  
  5. #include <utility>  
  6.    
  7. int main(int argc, char *argv[])  
  8. {  
  9.    using namespace boost::interprocess;  
  10.    typedef std::pair<doubleint> MyType;  
  11.    
  12.    if(argc == 1){  //Parent process  
  13.       //Remove shared memory on construction and destruction  
  14.       struct shm_remove  
  15.       {  
  16.          shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
  17.          ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
  18.       } remover;  
  19.    
  20.       //Construct managed shared memory  
  21.       managed_shared_memory segment(create_only, "MySharedMemory", 65536);  
  22.    
  23.       //Create an object of MyType initialized to {0.0, 0}  
  24.       MyType *instance = segment.construct<MyType>  
  25.          ("MyType instance")  //name of the object  
  26.          (0.0, 0);            //ctor first argument  
  27.    
  28.       //Create an array of 10 elements of MyType initialized to {0.0, 0}  
  29.       MyType *array = segment.construct<MyType>  
  30.          ("MyType array")     //name of the object  
  31.          [10]                 //number of elements  
  32.          (0.0, 0);            //Same two ctor arguments for all objects  
  33.    
  34.       //Create an array of 3 elements of MyType initializing each one  
  35.       //to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}...  
  36.       float float_initializer[3] = { 0.0, 1.0, 2.0 };  
  37.       int   int_initializer[3]   = { 0, 1, 2 };  
  38.    
  39.       MyType *array_it = segment.construct_it<MyType>  
  40.          ("MyType array from it")   //name of the object  
  41.          [3]                        //number of elements  
  42.          ( &float_initializer[0]    //Iterator for the 1st ctor argument  
  43.          , &int_initializer[0]);    //Iterator for the 2nd ctor argument  
  44.    
  45.       //Launch child process  
  46.       std::string s(argv[0]); s += " child ";  
  47.       if(0 != std::system(s.c_str()))  
  48.          return 1;  
  49.    
  50.    
  51.       //Check child has destroyed all objects  
  52.       if(segment.find<MyType>("MyType array").first ||  
  53.          segment.find<MyType>("MyType instance").first ||  
  54.          segment.find<MyType>("MyType array from it").first)  
  55.          return 1;  
  56.    }  
  57.    else{  
  58.       //Open managed shared memory  
  59.       managed_shared_memory segment(open_only, "MySharedMemory");  
  60.    
  61.       std::pair<MyType*, managed_shared_memory::size_type> res;  
  62.    
  63.       //Find the array  
  64.       res = segment.find<MyType> ("MyType array");  
  65.       //Length should be 10  
  66.       if(res.second != 10) return 1;  
  67.    
  68.       //Find the object  
  69.       res = segment.find<MyType> ("MyType instance");  
  70.       //Length should be 1  
  71.       if(res.second != 1) return 1;  
  72.    
  73.       //Find the array constructed from iterators  
  74.       res = segment.find<MyType> ("MyType array from it");  
  75.       //Length should be 3  
  76.       if(res.second != 3) return 1;  
  77.    
  78.       //We're done, delete all the objects  
  79.       segment.destroy<MyType>("MyType array");  
  80.       segment.destroy<MyType>("MyType instance");  
  81.       segment.destroy<MyType>("MyType array from it");  
  82.    }  
  83.    return 0;  
  84. }  

 

为共享内存使用一个偏移智能指针

Boost.Interprocess提供offset_ptr智能指针家族做为一个偏移指针,它用来存储偏移指针地址与对象地址的距离。当offset_ptr置于共享内存段中时,它能安全的指向这块共享内存段中的对象,甚至当内存段在不同的进程映射到不同的基地址时也能正常工作。

这使得带指针成员的对象能够放置在共享内存中。例如,如果我们想在共享内存中创建一个链表:

  
  
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <boost/interprocess/offset_ptr.hpp>  
  3.    
  4. using namespace boost::interprocess;  
  5.    
  6. //Shared memory linked list node  
  7. struct list_node  
  8. {  
  9.    offset_ptr<list_node> next;  
  10.    int                   value;  
  11. };  
  12.    
  13. int main ()  
  14. {  
  15.    //Remove shared memory on construction and destruction  
  16.    struct shm_remove  
  17.    {  
  18.       shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
  19.       ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
  20.    } remover;  
  21.    
  22.    //Create shared memory  
  23.    managed_shared_memory segment(create_only,  
  24.                                  "MySharedMemory",  //segment name  
  25.                                  65536);  
  26.    
  27.    //Create linked list with 10 nodes in shared memory  
  28.    offset_ptr<list_node> prev = 0, current, first;  
  29.    
  30.    int i;  
  31.    for(i = 0; i < 10; ++i, prev = current){  
  32.       current = static_cast<list_node*>(segment.allocate(sizeof(list_node)));  
  33.       current->value = i;  
  34.       current->next  = 0;  
  35.    
  36.       if(!prev)  
  37.          first = current;  
  38.       else  
  39.          prev->next = current;  
  40.    }  
  41.    
  42.    //Communicate list to other processes  
  43.    //. . .  
  44.    //When done, destroy list  
  45.    for(current = first; current; /**/){  
  46.       prev = current;  
  47.       current = current->next;  
  48.       segment.deallocate(prev.get());  
  49.    }  
  50.    return 0;  
  51. }  

为了更好处理基本数据结构,Boost.Interprocess提供了类似于vector、list、map的容器,因此你能避免这些数据结构手册,就像使用标准容器一样。

 

在共享内存中创建容器(vector)

Boost.Interprocess允许在共享内存和内存映射文件中创建复杂的对象。例如,我们可以在共享内存中创建类STL容器。为了做到这点,我们仅需创建一个特殊(控制)的共享内存片段,申明一个Boost.Interprocess分配器然后创建像其他对象一样在共享内存中创建vector.

这个允许在共享内存中创建复杂结构的类是 boost::interprocess::managed_shared_memory,它使用起来非常简单。只要不带参数执行下面这个例子:

  
  
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <boost/interprocess/containers/vector.hpp>  
  3. #include <boost/interprocess/allocators/allocator.hpp>  
  4. #include <string>  
  5. #include <cstdlib> //std::system  
  6.    
  7. using namespace boost::interprocess;  
  8.    
  9. //Define an STL compatible allocator of ints that allocates from the managed_shared_memory.  
  10. //This allocator will allow placing containers in the segment  
  11. typedef allocator<int, managed_shared_memory::segment_manager>  ShmemAllocator;  
  12.    
  13. //Alias a vector that uses the previous STL-like allocator so that allocates  
  14. //its values from the segment  
  15. typedef vector<int, ShmemAllocator> MyVector;  
  16.    
  17. //Main function. For parent process argc == 1, for child process argc == 2  
  18. int main(int argc, char *argv[])  
  19. {  
  20.    if(argc == 1){ //Parent process  
  21.       //Remove shared memory on construction and destruction  
  22.       struct shm_remove  
  23.       {  
  24.          shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
  25.          ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
  26.       } remover;  
  27.    
  28.       //Create a new segment with given name and size  
  29.       managed_shared_memory segment(create_only, "MySharedMemory", 65536);  
  30.    
  31.       //Initialize shared memory STL-compatible allocator  
  32.       const ShmemAllocator alloc_inst (segment.get_segment_manager());  
  33.    
  34.       //Construct a vector named "MyVector" in shared memory with argument alloc_inst  
  35.       MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);  
  36.    
  37.       for(int i = 0; i < 100; ++i)  //Insert data in the vector  
  38.          myvector->push_back(i);  
  39.    
  40.       //Launch child process  
  41.       std::string s(argv[0]); s += " child ";  
  42.       if(0 != std::system(s.c_str()))  
  43.          return 1;  
  44.    
  45.       //Check child has destroyed the vector  
  46.       if(segment.find<MyVector>("MyVector").first)  
  47.          return 1;  
  48.    }  
  49.    else//Child process  
  50.       //Open the managed segment  
  51.       managed_shared_memory segment(open_only, "MySharedMemory");  
  52.    
  53.       //Find the vector using the c-string name  
  54.       MyVector *myvector = segment.find<MyVector>("MyVector").first;  
  55.    
  56.       //Use vector in reverse order  
  57.       std::sort(myvector->rbegin(), myvector->rend());  
  58.    
  59.       //When done, destroy the vector from the segment  
  60.       segment.destroy<MyVector>("MyVector");  
  61.    }  
  62.    
  63.    return 0;  
  64. };  

父进程将创建一个特殊的共享内存类,它允许许多具名复杂数据结构的构建。子进程(译注:原文这里误写为父进程)带参数的执行同一个程序,打开共享内存,使用vector并且删除它。

 

在共享内存中创建映射表(map)

与vector一样,Boost.Interprocess允许在共享内存和内存映射文件中创建映射表。唯一的不同点在于,与标准关联容器一样,当分配器传入到构造函数中时,Boost.Interprocess的map也需要定义比较函数:

  
  
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <boost/interprocess/containers/map.hpp>  
  3. #include <boost/interprocess/allocators/allocator.hpp>  
  4. #include <functional>  
  5. #include <utility>  
  6.    
  7. int main ()  
  8. {  
  9.    using namespace boost::interprocess;  
  10.    
  11.    //Remove shared memory on construction and destruction  
  12.    struct shm_remove  
  13.    {  
  14.       shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
  15.       ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
  16.    } remover;  
  17.    
  18.    //Shared memory front-end that is able to construct objects  
  19.    //associated with a c-string. Erase previous shared memory with the name  
  20.    //to be used and create the memory segment at the specified address and initialize resources  
  21.    managed_shared_memory segment  
  22.       (create_only  
  23.       ,"MySharedMemory" //segment name  
  24.       ,65536);          //segment size in bytes  
  25.    
  26.    //Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,  
  27.    //so the allocator must allocate that pair.  
  28.    typedef int    KeyType;  
  29.    typedef float  MappedType;  
  30.    typedef std::pair<const intfloat> ValueType;  
  31.    
  32.    //Alias an STL compatible allocator of for the map.  
  33.    //This allocator will allow to place containers  
  34.    //in managed shared memory segments  
  35.    typedef allocator<ValueType, managed_shared_memory::segment_manager>  
  36.       ShmemAllocator;  
  37.    
  38.    //Alias a map of ints that uses the previous STL-like allocator.  
  39.    //Note that the third parameter argument is the ordering function  
  40.    //of the map, just like with std::map, used to compare the keys.  
  41.    typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;  
  42.    
  43.    //Initialize the shared memory STL-compatible allocator  
  44.    ShmemAllocator alloc_inst (segment.get_segment_manager());  
  45.    
  46.    //Construct a shared memory map.  
  47.    //Note that the first parameter is the comparison function,  
  48.    //and the second one the allocator.  
  49.    //This the same signature as std::map's constructor taking an allocator  
  50.    MyMap *mymap =  
  51.       segment.construct<MyMap>("MyMap")      //object name  
  52.                                  (std::less<int>() //first  ctor parameter  
  53.                                  ,alloc_inst);     //second ctor parameter  
  54.    
  55.    //Insert data in the map  
  56.    for(int i = 0; i < 100; ++i){  
  57.       mymap->insert(std::pair<const intfloat>(i, (float)i));  
  58.    }  
  59.    return 0;  
  60. }  

更多例子(包含容器的容器),可参考章节“容器的容器”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值