Shared Memory

Shared memory is typically the fastest form of interprocess communicatioin. It provides a memory area that is shared between processes. One process can write data to the area and another process can read it.

In Boost.Interrprocess the class boost::interprocess::shared_memory_object is used to represent shared memory.

1. create shared memory

#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream> using namespace boost::interprocess; int main() {
shared_memory_object shdmem(open_or_create, "Boost", read_write);
shdmem.truncate();
std::cout << shdmem.get_name() << std::endl;
offset_t size;
if (shdmem.get_size(size)) {
std::cout << size << std::endl;
} return ;
}

shared_memory_object expects three parameters. The first parameter specifies whether the shared memory should be created or just opened. boost::interprocess::open_or_create will open shared memory if it already exists or create shared memory if it doesn't.

The name is specified by the second parameter passed to the constructor of boost::interprocess::shared_memeory_object.

The third parameter determines how a process can access shared memory. boost::interprocess::read_write says the process has read-write access.

After creating an object of type boost::interprocess::shared_memory_object, a corresponding shared memory block will exist within the operating system. The size of this memory area is initially 0. To use the area, call truncate(), passing in the size of the shared memory in bytes.

get_name() and get_size() can be used to query the name and the size of the shared memory.

2. Because shared memory is used to exchange data betwen different processes, each process needs to map the shared memory into its address space.

#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream> using namespace boost::interprocess; int main() {
shared_memory_object shdmem(open_or_create, "Boost", read_write);
shdmem.truncate();
mapped_region region(shdmem, read_write);
std::cout << std::hex << region.get_address() << std::endl;
std::cout << std::dec << region.get_size() << std::endl;
int* i1 = static_cast<int*>(region.get_address());
*i1 = ; mapped_region region2(shdmem, read_only);
std::cout << std::hex << region2.get_address() << std::endl;
std::cout << std::dec << region2.get_size() << std::endl;
int* i2 = static_cast<int*>(region2.get_address());
std::cout << *i2 << std::endl; bool removed = shared_memory_object::remove("Boost");
std::cout << std::boolalpha << removed << std::endl;
return ;
}

输出为:

0x7f6abbf76000

1024

0x7f6abbf74000

1024

99

true

boost::interprocess::shared_memory_object must be passed as the first parameter to the constructor of boost::interprocess::mapped_region. The second parameter determines whether access to the memory area is read-only or read-write. The address and the size of the mapped memory area is written to standard output using the member funcitons get_address() and get_size(). The return value of get_address() is different for each object.

As the example above, region writes the number 99 to the beginning of the shared memory. region2 the reads the same location in shared memory and writes the number to the standard ouptu stream. Even though region and region2 represent different memory areas within the process, the program print2 99 because both memory areas access the same underlying shared memory.

To delete shared memory, boost::interprocess::shared_memory_object offers the static member function remove(), which takes the name of the shared memory to be deleted as a parameter.

If remove() is never called, the shared memory continues to exist even if the program terminates. Whether or not the shared memory is automatically deleted depends on the underlying operating system. Windows and many Unix operating systems, including Linux, automatically delete shared memory once the system is restarted.

Managed Shared Memory

class boost::interprocess::shared_memory_object which can be used to create and manage shared memory. In pratice, this class is raraly used because it requires the program to read and write individual bytes from and to the shared memory. Boost.Interprocess provides

1. boost::interprocess::managed_shared_memory to support managed shared memory. This class lets you instantiate objects that have their memory located in shared memory, making the objects automatically available to any program that accesses the same shared memory.

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream> using namespace boost::interprocess; int main() {
shared_memory_object::remove("Boost");
managed_shared_memory managed_shm(open_or_create, "Boost", );
int* i = managed_shm.construct<int>("Integer")();
std::cout << *i << std::endl;
std::pair<int*, std::size_t> p = managed_shm.find<int>("Integer");
if (p.first) {
std::cout << *p.first << std::endl;
} return ;
}

In regular shared memory, individual bytes are directly accessed to read or write data. Managed shared memory uses member functions such as construct(), which expects a type as a template parameter. The member function expects a name to denote the object created in the managed shared memory.

To access a particular object in managed shared memory, the member function find() is used. By passing the name of the object to find, find() returns either a pointer to the object, or in case no object with the given name was found(), 0.

2.

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream> using namespace boost::interprocess; int main() {
shared_memory_object::remove("Boost");
managed_shared_memory managed_shm(open_or_create, "Boost", );
int* i = managed_shm.construct<int>("Integer")[]();
std::cout << *i << std::endl;
std::pair<int*, std::size_t> p = managed_shm.find<int>("Integer");
if (p.first) {
std::cout << *p.first << std::endl;
std::cout << p.second << std::endl;
} return ;
}

Like the example above, an array with ten elements of type int is created by providing the value 10 enclosed by square brackets after the call to construct(). The same 10 is written to the standard output stream using the member variable second. Please note that all ten elements in the array are initialized with the value 99. construct() will fail if an object already exists with the given name in the managed shared memory. In this case, construct() returns 0 and no initialization occurs.

3. remove objects in shared memory

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream> using namespace boost::interprocess; int main()
{
shared_memory_object::remove("Boost");
managed_shared_memory managed_shm{open_or_create, "Boost", };
int *i = managed_shm.find_or_construct<int>("Integer")();
std::cout << *i << std::endl;
managed_shm.destroy<int>("Integer");
std::pair<int*, std::size_t> p = managed_shm.find<int>("Integer");
std::cout << p.first << std::endl;
}

The name of the object to be deleted is passed as the only parameter to destroy(). The return value of type bool can be checked to verify whether the given object was found and deleted successfully. Because an object will always be deleted if found, a return value of false indicates that no object with the given name was found.

4. putting strings into shared memory

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <iostream> using namespace boost::interprocess; int main()
{
shared_memory_object::remove("Boost");
managed_shared_memory managed_shm{open_or_create, "Boost", };
typedef allocator<char, managed_shared_memory::segment_manager> CharAllocator;
typedef basic_string<char, std::char_traits<char>, CharAllocator> string;
string *s = managed_shm.find_or_construct<string>("String")("Hello!", managed_shm.get_segment_manager());
s->insert(, ", world");
std::cout << *s << std::endl;
return ;
}

To create a string that will allocate memory in the same managed shared memory it resides in, a corresponding type must be defined. The new string type must use an allocator provided by Boost.Interprocess instead of the default allocator provided by the standard.

Boost.Interprocess provides implementations for many other containers from the standard library. For example, boost::interprocess::vector and boost::interprocess::map are defined in boost/interprocess/containers/vector.hpp and boost/interprocess/containers/map.hpp, respectively.

5. atomic access on a managed shared memory

If two programs try to create objects with different names in the managed shared memory, the access is serialized accordingly. To execute multiple operations at one time without being interrupted by operations from a different process, use the member function atomic_func().

#include <boost/interprocess/managed_shared_memory.hpp>
#include <functional>
#include <iostream> using namespace boost::interprocess; void construct_objects(managed_shared_memory &managed_shm)
{
managed_shm.construct<int>("Integer")();
managed_shm.construct<float>("Float")(3.14);
} int main()
{
shared_memory_object::remove("Boost");
managed_shared_memory managed_shm{open_or_create, "Boost", };
auto atomic_construct = std::bind(construct_objects, std::ref(managed_shm));
managed_shm.atomic_func(atomic_construct);
std::cout << *managed_shm.find<int>("Integer").first << std::endl;
std::cout << *managed_shm.find<float>("Float").first << std::endl;
return ;
}

atomic_func() expects as its single parameter a function that takes no parameters and has no return value. The passed function will be called in a fashion that ensures exclusive access to the managed shared memory. However, exclusive access is only ensured if all other processes that access the managed shared memory also use atomic_func(). If another process has a pointer to an object within the managed shared memory, it could access and modify this object using its pointer.

Synchronization

Boost.Interprocess provides two kinds of synchronization objects: anonymous objects are directly stored in the shared memory, which makes them automatically available to all processes. Named objects are managed by the operating system, are not stored in the shared memory, and can be referenced from programs by name.

1. named_mutex  interprocess_mutex

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <iostream> using namespace boost::interprocess; int main()
{
managed_shared_memory managed_shm{open_or_create, "shm", };
int *i = managed_shm.find_or_construct<int>("Integer")();
named_mutex named_mtx{open_or_create, "mtx"};
named_mtx.lock();
++(*i);
std::cout << *i << std::endl;
named_mtx.unlock();
return 0;
}

boost::interprocess::named_mutex expects a parameter specifying whether the mutex should be created or opened and a name for the mutex. Every process that knows the name can open the same mutex.

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <iostream> using namespace boost::interprocess; int main()
{
managed_shared_memory managed_shm{open_or_create, "shm", };
int *i = managed_shm.find_or_construct<int>("Integer")();
interprocess_mutex *mtx =
managed_shm.find_or_construct<interprocess_mutex>("mtx")();
mtx->lock();
++(*i);
std::cout << *i << std::endl;
mtx->unlock();
return ;
}

The mutex is now stored directly in shared memory. This can be done with the member functions construct() or find_or_construct() from the class boost::interprocess::managed_shared_memory.

boost Shared Memory的更多相关文章

  1. C++: Virtual Table and Shared Memory

    See at: 补充栏3: C++对象和共享内存 (叙述内容和Link1的内容基本一致) <C++网络编程 卷1:运用ACE和模式消除复杂性> <C++ Network Progra ...

  2. ORA-27101: shared memory realm does not exist

    Oracle Error Tips by Burleson Consulting Oracle docs note this about ORA-27101: ORA-27101: shared me ...

  3. shared memory realm does not exist

    有天启动ORACLE,碰到如下问题 提示ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist 解决 ...

  4. Oracle重启 error: ora-01034:oracle not available ora-27101:shared memory realm does not exist

    error: ora-01034:oracle not available ora-27101:shared memory realm does not exist 苦咖啡 他的博客中一篇文章完美的解 ...

  5. zabbix登陆问题:cannot allocate shared memory for collector

    问题说明:在一台zabbix被监控服务器上(64位centos6.8系统,64G内容)启动zabbix_agent,发现进程无法启动,10050端口没有起来! 启动zabbix_agent进程没有报错 ...

  6. ORA-27101:shared memory realm does not exist的问题

    ORA-27101:shared memory realm does not exist的问题 登陆SQLPlus时出现: ORA-01034:ORACLE not avaiable ORA-2710 ...

  7. IPC:shared memory

    #include <stdio.h> #include <sys/shm.h> #include <sys/stat.h> int main () { int se ...

  8. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6666491 在前面一篇文章Android系统匿 ...

  9. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共 ...

随机推荐

  1. 如何在微信小程序中使用iconfont

    开篇废话 开发过小程序的童鞋肯定都会遇到这样的问题,当我们在小程序中使用iconfont官方推荐的方法插入字体时,我们总会得到一个打印机(滑稽).那么如何在小程序中正确的使用iconfont呢? 一. ...

  2. 「PHP开发APP接口实战009」日常安全防范之防SQL入和XSS攻击

    防SQL注入和XSS攻击通用过滤 首先在 /app/library/ 目录下创建 Security.php 文件并添加以下代码: <?php /** * * 防SQL注入和XSS攻击通用过滤 * ...

  3. oracle12.2 CDB PDB基本管理操作

    容器间切换 切换到对应的PDBSSQL> alter session set container=pdb1;Session altered.SQL> alter database open ...

  4. Flask框架视图多层装饰器问题

    Flask中的app.route装饰器 我们知道,在flask框架中,我们的路由匹配就是通过有参装饰器来实现的,我们看一个简单的例子: from flask import Flask, render_ ...

  5. Ubuntu查看端口使用情况,使用netstat命令:

    https://www.cnblogs.com/fly-book/p/9827128.html

  6. vue实现ajax请求(vue-resource和axios)

    1.vue-resouce实现ajax请求 vue1中主要用vue-resouce实现ajax请求, 2.1 引用vue-resouce 引入axios,直接在index.html文件中引入; 或者在 ...

  7. 爬虫中GET方法应用基本模型

    根据get方法,更改界面url从而获取信息 GET请求URL附带查询参数 POST请求保存在form表单中 分析百度贴吧url特点: 分析url https://tieba.baidu.com/f是贴 ...

  8. C++ bitset的使用

    bitset 一般代替 bool 数组使用,常用于优化空间,因为 bitset 中一个元素只占 1 bit. bitset 的大小在定义使就需要确定.如果想要不定长的 bitset,就需要使用 vec ...

  9. Convolutional Neural Networks(5):Pooling Layer

    池化层(Pooling layer)同样是收到了视觉神经科学的启发.在初级视觉皮层V1(Primary visual cortex)中,包含了许多复杂细胞(Complex cells),这些细胞对于图 ...

  10. 关于eclipse中的maven插件问题

    最近上课讲eclipse 中的maven插件 有一个坑确实比较坑,实际上就是一个配置的原因. 就是在eclipse中设置java 的buildpath的时候,一般不注意往往都设置成了jre的,这样的话 ...