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. String 类的常用方法

    format 是String类的一个非常有用的静态函数,可以将各类数据格式化为字符串并输出.其中format参数指定了输出的格式 toCharArray方法可以将字符串转为字符数组 getBytes方 ...

  2. 简单Spring整合JdbcTemplate

    实体类: public class User implements Serializable{ private Integer id; private String username; private ...

  3. xiugai2

    <div class="myLoading"> <div class="svg-wrap"> <svg width="8 ...

  4. php面试专题---20、MySQL的安全性考点

    php面试专题---20.MySQL的安全性考点 一.总结 一句话总结: 还是得多看视频,教程看的浮光掠影,容易get不到重点:比如预处理防sql注入之前是挺熟,后面就忘记了,而且看文章get不到点 ...

  5. css3的各种属性的讲解

    1.渐变(gradients) 水平渐变:linear gradient 语法:background:linear-gradient(direction,color1,color2); directi ...

  6. python数据类

    前言 之前有写过一篇python元类的笔记,元类主要作用就是在要创建的类中使用参数metaclass=YourMetaclass调用自定义的元类,这样就可以为所有调用了这个元类的类添加相同的属性了. ...

  7. day22—一个AngularJS框架应用toDoList

    转行学开发,代码100天——2018-04-07 今天用AngularJS照着课程写了一个案例,即toDoList,记事清单效果. 主要实现以下效果: 1.通过文本框添加内容,同时添加事件列表.主要用 ...

  8. SEC5 - MySQL 查询语句--------------进阶1:基础查询

    # 进阶1:基础查询 /* 语法: select 查询列表 from 表名: 特点: 1.查询列表可以是:表中的字段.常量值.表达式.表达式.函数 2.查询的结果是一个虚拟的表格 如何执行:执行谁,请 ...

  9. Python科学计算三维可视化(整理完结)

    中国MOOC<Pyhton计算计算三维可视化>总结 课程url:here ,教师:黄天宇,嵩天 下文的图片和问题,答案都是从eclipse和上完课后总结的,转载请声明. Python数据三 ...

  10. mysql: "Warning: Using a password on the command line interface can be insecure." 解决方法

    错误重现: 命令行或者shell脚本中执行以下命令,如果您当前服务器mysql版本是大于5.6的,则会出现警告:Warning: Using a password on the command lin ...