Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Quick Guide for the Impatient

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 16. Boost.Interprocess

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Вы можете просто выделить часть разделяемого сегмента памяти, скопировать сообщение в этот буфер, отправить смещение этой части совместно используемой памяти в другой процесс. Давайте посмотрим на пример:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <sstream>
int main (int argc, char *argv[])
{
   using namespace boost::interprocess;
   if(argc == 1){  //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove
      {
         shm_remove() {  shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){  shared_memory_object::remove("MySharedMemory"); }
      } remover;
      //Create a managed shared memory segment
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);
      //Allocate a portion of the segment (raw memory)
      managed_shared_memory::size_type free_memory = segment.get_free_memory();
      void * shptr = segment.allocate(1024/*bytes to allocate*/);
      //Check invariant
      if(free_memory <= segment.get_free_memory())
         return 1;
      //An handle from the base address can identify any byte of the shared
      //memory segment even if it is mapped in different base addresses
      managed_shared_memory::handle_t handle = segment.get_handle_from_address(shptr);
      std::stringstream s;
      s << argv[0] << " " << handle;
      s << std::ends;
      //Launch child process
      if(0 != std::system(s.str().c_str()))
         return 1;
      //Check memory has been freed
      if(free_memory != segment.get_free_memory())
         return 1;
   }
   else{
      //Open managed segment
      managed_shared_memory segment(open_only, "MySharedMemory");
      //An handle from the base address can identify any byte of the shared
      //memory segment even if it is mapped in different base addresses
      managed_shared_memory::handle_t handle = 0;
      //Obtain handle value
      std::stringstream s; s << argv[1]; s >> handle;
      //Get buffer local address from handle
      void *msg = segment.get_address_from_handle(handle);
      //Deallocate previously allocated memory
      segment.deallocate(msg);
   }
   return 0;
}

Вы хотите создавать объекты в сегменте общей памяти, давая им имя строки, чтобы любой другой процесс мог найти, использовать и удалить их из сегмента, когда объекты больше не нужны. Пример:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <cstddef>
#include <cassert>
#include <utility>
int main(int argc, char *argv[])
{
   using namespace boost::interprocess;
   typedef std::pair<double, int> MyType;
   if(argc == 1){  //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove
      {
         shm_remove() { shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
      } remover;
      //Construct managed shared memory
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);
      //Create an object of MyType initialized to {0.0, 0}
      MyType *instance = segment.construct<MyType>
         ("MyType instance")  //name of the object
         (0.0, 0);            //ctor first argument
      //Create an array of 10 elements of MyType initialized to {0.0, 0}
      MyType *array = segment.construct<MyType>
         ("MyType array")     //name of the object
         [10]                 //number of elements
         (0.0, 0);            //Same two ctor arguments for all objects
      //Create an array of 3 elements of MyType initializing each one
      //to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}...
      float float_initializer[3] = { 0.0, 1.0, 2.0 };
      int   int_initializer[3]   = { 0, 1, 2 };
      MyType *array_it = segment.construct_it<MyType>
         ("MyType array from it")   //name of the object
         [3]                        //number of elements
         ( &float_initializer[0]    //Iterator for the 1st ctor argument
         , &int_initializer[0]);    //Iterator for the 2nd ctor argument
      //Launch child process
      std::string s(argv[0]); s += " child ";
      if(0 != std::system(s.c_str()))
         return 1;
      //Check child has destroyed all objects
      if(segment.find<MyType>("MyType array").first ||
         segment.find<MyType>("MyType instance").first ||
         segment.find<MyType>("MyType array from it").first)
         return 1;
   }
   else{
      //Open managed shared memory
      managed_shared_memory segment(open_only, "MySharedMemory");
      std::pair<MyType*, managed_shared_memory::size_type> res;
      //Find the array
      res = segment.find<MyType> ("MyType array");
      //Length should be 10
      if(res.second != 10) return 1;
      //Find the object
      res = segment.find<MyType> ("MyType instance");
      //Length should be 1
      if(res.second != 1) return 1;
      //Find the array constructed from iterators
      res = segment.find<MyType> ("MyType array from it");
      //Length should be 3
      if(res.second != 3) return 1;
      //We're done, delete all the objects
      segment.destroy<MyType>("MyType array");
      segment.destroy<MyType>("MyType instance");
      segment.destroy<MyType>("MyType array from it");
   }
   return 0;
}

Boost.Interprocessпредлагает семейство умных указателей offset_ptr в качестве офсетного указателя, который хранит расстояние между адресом самого офсетного указателя и адресом заостренного объекта. Когда offset_ptr помещается в сегмент общей памяти, он может безопасно указывать объекты, хранящиеся в одном сегменте общей памяти, даже если сегмент отображается в разных базовых адресах в разных процессах.

Это позволяет размещать объекты с указателями в общей памяти. Например, если мы хотим создать связанный список в общей памяти:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/offset_ptr.hpp>
using namespace boost::interprocess;
//Shared memory linked list node
struct list_node
{
   offset_ptr<list_node> next;
   int                   value;
};
int main ()
{
   //Remove shared memory on construction and destruction
   struct shm_remove
   {
      shm_remove() { shared_memory_object::remove("MySharedMemory"); }
      ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
   } remover;
   //Create shared memory
   managed_shared_memory segment(create_only,
                                 "MySharedMemory",  //segment name
                                 65536);
   //Create linked list with 10 nodes in shared memory
   offset_ptr<list_node> prev = 0, current, first;
   int i;
   for(i = 0; i < 10; ++i, prev = current){
      current = static_cast<list_node*>(segment.allocate(sizeof(list_node)));
      current->value = i;
      current->next  = 0;
      if(!prev)
         first = current;
      else
         prev->next = current;
   }
   //Communicate list to other processes
   //. . .
   //When done, destroy list
   for(current = first; current; /**/){
      prev = current;
      current = current->next;
      segment.deallocate(prev.get());
   }
   return 0;
}

Чтобы помочь с базовыми структурами данных,Boost.Interprocessпредлагает контейнеры, такие как вектор, список, карта, поэтому вы можете избежать этих структур данных вручную, как и в стандартных контейнерах.

Boost.Interprocessпозволяет создавать сложные объекты в общей памяти и картированных файлах памяти. Например, мы можем создавать STL-подобные контейнеры в общей памяти. Для этого нам просто нужно создать специальный (управляемый) сегмент совместно используемой памяти, объявитьBoost.Interprocessаллокатором и построить вектор в совместно используемой памяти, если это был какой-либо другой объект.

Класс, который позволяет использовать эти сложные структуры в общей памяти, называется<boost::interprocess::managed_shared_memory>. Выполните этот пример без аргументов:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <string>
#include <cstdlib> //std::system
using namespace boost::interprocess;
//Define an STL compatible allocator of ints that allocates from the managed_shared_memory.
//This allocator will allow placing containers in the segment
typedef allocator<int, managed_shared_memory::segment_manager>  ShmemAllocator;
//Alias a vector that uses the previous STL-like allocator so that allocates
//its values from the segment
typedef vector<int, ShmemAllocator> MyVector;
//Main function. For parent process argc == 1, for child process argc == 2
int main(int argc, char *argv[])
{
   if(argc == 1){ //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove
      {
         shm_remove() { shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
      } remover;
      //Create a new segment with given name and size
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);
      //Initialize shared memory STL-compatible allocator
      const ShmemAllocator alloc_inst (segment.get_segment_manager());
      //Construct a vector named "MyVector" in shared memory with argument alloc_inst
      MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);
      for(int i = 0; i < 100; ++i)  //Insert data in the vector
         myvector->push_back(i);
      //Launch child process
      std::string s(argv[0]); s += " child ";
      if(0 != std::system(s.c_str()))
         return 1;
      //Check child has destroyed the vector
      if(segment.find<MyVector>("MyVector").first)
         return 1;
   }
   else{ //Child process
      //Open the managed segment
      managed_shared_memory segment(open_only, "MySharedMemory");
      //Find the vector using the c-string name
      MyVector *myvector = segment.find<MyVector>("MyVector").first;
      //Use vector in reverse order
      std::sort(myvector->rbegin(), myvector->rend());
      //When done, destroy the vector from the segment
      segment.destroy<MyVector>("MyVector");
   }
   return 0;
}

Родительский процесс создаст специальный общий класс памяти, который позволит легко построить множество сложных структур данных, связанных с именем. Родительский процесс выполняет ту же программу с дополнительным аргументом, поэтому детский процесс открывает общую память и использует вектор и стирает его.

Как и вектор,Boost.Interprocessпозволяет создавать карты в общей памяти и отображаемые в памяти файлы. Разница лишь в том, что, подобно стандартным ассоциативным контейнерам,Boost.Interprocessна карте также нужен сравнительный функтор, когда распределитель передается в конструкторе:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <functional>
#include <utility>
int main ()
{
   using namespace boost::interprocess;
   //Remove shared memory on construction and destruction
   struct shm_remove
   {
      shm_remove() { shared_memory_object::remove("MySharedMemory"); }
      ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
   } remover;
   //Shared memory front-end that is able to construct objects
   //associated with a c-string. Erase previous shared memory with the name
   //to be used and create the memory segment at the specified address and initialize resources
   managed_shared_memory segment
      (create_only
      ,"MySharedMemory" //segment name
      ,65536);          //segment size in bytes
   //Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
   //so the allocator must allocate that pair.
   typedef int    KeyType;
   typedef float  MappedType;
   typedef std::pair<const int, float> ValueType;
   //Alias an STL compatible allocator of for the map.
   //This allocator will allow to place containers
   //in managed shared memory segments
   typedef allocator<ValueType, managed_shared_memory::segment_manager>
      ShmemAllocator;
   //Alias a map of ints that uses the previous STL-like allocator.
   //Note that the third parameter argument is the ordering function
   //of the map, just like with std::map, used to compare the keys.
   typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;
   //Initialize the shared memory STL-compatible allocator
   ShmemAllocator alloc_inst (segment.get_segment_manager());
   //Construct a shared memory map.
   //Note that the first parameter is the comparison function,
   //and the second one the allocator.
   //This the same signature as std::map's constructor taking an allocator
   MyMap *mymap =
      segment.construct<MyMap>("MyMap")      //object name
                                 (std::less<int>() //first  ctor parameter
                                 ,alloc_inst);     //second ctor parameter
   //Insert data in the map
   for(int i = 0; i < 100; ++i){
      mymap->insert(std::pair<const int, float>(i, (float)i));
   }
   return 0;
}

Для более продвинутого примера, включающего контейнеры контейнеров, см. разделКонтейнеры контейнеров.


PrevUpHomeNext

Статья Quick Guide for the Impatient раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 16. Boost.Interprocess может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 16. Boost.Interprocess ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-07-04 23:56:11/0.0081310272216797/0