Boost.Interprocess翻译-快速入门

时间:2022-03-31 05:33:01

Quick Guide for the Impatient

入门指南

Using shared memory as a pool of unnamed memory blocks
Creating named shared memory objects
Using an offset smart pointer for shared memory
Creating vectors in shared memory
Creating maps in shared memory
使用共享内存作为无名内存块池(a pool of unnamed memory blocks)
创建命名共享内存对象(named shared memory objects)
在共享内存上使用智能偏移指针(offset smart pointer)
在共享内存上创建vectors
在共享内存上创建maps

Using shared memory as a pool of unnamed memory blocks

使用共享内存作为无名内存块池(a pool of unnamed memory blocks)

You can just allocate a portion of a shared memory segment, copy the message to that buffer, send the offset of that portion of shared memory to another process, and you are done. Let's see the example:

 

 

你只需要分配共享内存段中的一块,将message拷贝到那里,将共享内存中该块的偏移地址发送给 另一个进程,这就是所有你需要做的。让我们看看例子:

 

 

#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)
// 申请共享内存中的一块段
std::size_t 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
// 检查是否如果子进程释放了句柄
// 空闲内存大小应等于free_memory

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;
}

 

 

Creating named shared memory objects

创建命名共享内存对象(named shared memory objects)

You want to create objects in a shared memory segment, giving a string name to them so that any other process can find, use and delete them from the segment when the objects are not needed anymore. Example:

 

 

你可在共享内存段上创建对象,并给对象指定一个字符串名字,这样其他进程就可以通过名字查找, 使用,并当不再需要这些对象是删除它们。举例:

 

 

#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)
managed_shared_memory segment(create_only, "MySharedMemory", 65536);

//Create an object of MyType initialized to {0.0, 0}
// 创建一个MyType类型的对象并初始化为 {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}
// 创建10个元素的MyType类型数组,并初始化为{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}...
// 创建一个3个元素的MyType类型的数组并初始化
// 它们的值分别为 {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*, std::size_t> res;

//Find the array
// 查找数组
res = segment.find<MyType> ("MyType array");
//Length should be 10
// 长度应该是10
if(res.second != 10) return 1;

//Find the object
// 查找对象
res = segment.find<MyType> ("MyType instance");
//Length should be 1
// 长度应该是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
// 长度应该是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;
}

 

 

Using an offset smart pointer for shared memory

在共享内存上使用智能偏移指针(offset smart pointer)

Boost.Interprocess offers offset_ptr smart pointer family as an offset pointer that stores the distance between the address of the offset pointer itself and the address of the pointed object. When offset_ptr is placed in a shared memory segment, it can point safely objects stored in the same shared memory segment, even if the segment is mapped in different base addresses in different processes.

Boost.Interprocess 提供了offset_ptr智能指针( smart pointer),作为偏移指针来讲, 它存储了它所指向的对象地址和指针自身地址之间的距离。 当offset_ptr被放置到共享内存段上时,即使共享被映射到不同的 地址空间,它也能安全地指向共享内存段上的对象。

This allows placing objects with pointer members in shared memory. For example, if we want to create a linked list in shared memory:

这就允许将带有指针成员的对象放置到共享内存中,比如,我们打算在共享内存上创建链表。

 

 

#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;
}

 

 

To help with basic data structures, Boost.Interprocess offers containers like vector, list, map, so you can avoid these manual data structures just like with standard containers.

在基本数据结构的帮助下,Boost.Interprocess提供了 诸如vector, list, map等容器,所以你可以避免手工建立这些跟标准库相似的数据结构。

Creating vectors in shared memory

在共享内存上创建vectors

Boost.Interprocess allows creating complex objects in shared memory and memory mapped files. For example, we can construct STL-like containers in shared memory. To do this, we just need to create a special (managed) shared memory segment, declare a Boost.Interprocess allocator and construct the vector in shared memory just if it was any other object.

Boost.Interprocess 允许在共享内存和内存映射文件上创建复杂对象。例如,我们可以在共享内存上构造类STL容器。 为了做到这点,我们只需创建一个共享内存段(或者托管的共享内存段), 声明一个Boost.Interprocess分配器,就可在共享 内存上构建vector,就像创建其他任何对象一样。

The class that allows this complex structures in shared memory is called boost::interprocess::managed_shared_memory and it's easy to use. Just execute this example without arguments:

允许在共享内存创建复杂结构的类是 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;
};

 

 

The parent process will create an special shared memory class that allows easy construction of many complex data structures associated with a name. The parent process executes the same program with an additional argument so the child process opens the shared memory and uses the vector and erases it.

父进程创建一个特定的共享内存类,它允许轻松构建多个带有名称的复杂数据结构。 父进程用一个额外参数执行同一个程序,于是子进程打开共享内存并使用并 删除vector。

Creating maps in shared memory

在共享内存上创建maps

Just like a vector, Boost.Interprocess allows creating maps in shared memory and memory mapped files. The only difference is that like standard associative containers,Boost.Interprocess's map needs also the comparison functor when an allocator is passed in the constructor:

就像vector一样,Boost.Interprocess 允许在共享内存和内存映射文件上创建maps。唯一的不同是就像其他的关联容器一样, Boost.Interprocessmap需要 在构造函数传入分配器时,还要传入比较函数。

 

 

#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
// 定义一个map的与STL兼容分配器的别名,这个分配器允许将容器放到托管内存段上。
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.
// 定义int型的,使用上面的类STL分配器的map的别名。
// 注意第三个参数是map的排序函数,就像std::map一样,用来比较map的key
typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;

//Initialize the shared memory STL-compatible allocator
// 初始化共享内存的STL兼容分配器
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
// 构造共享内存map
// 注意第一个参数是比较函数,第二个参数是分配器,
// 这和std::map带分配器参数的构造函数有相同的签名
MyMap *mymap =
segment.construct<MyMap>("MyMap") //object name
(std::less<int>() //first ctor parameter
,alloc_inst); //second ctor parameter

//Insert data in the map
// 在map上插入数据
for(int i = 0; i < 100; ++i){
mymap->insert(std::pair<const int, float>(i, (float)i));
}
return 0;
}

 

 

For a more advanced example including containers of containers, see the section Containers of containers.

更多高级示例,包括容器的容器,请看容器的容器.