boost Shared Memory
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的更多相关文章
- C++: Virtual Table and Shared Memory
See at: 补充栏3: C++对象和共享内存 (叙述内容和Link1的内容基本一致) <C++网络编程 卷1:运用ACE和模式消除复杂性> <C++ Network Progra ...
- 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 ...
- shared memory realm does not exist
有天启动ORACLE,碰到如下问题 提示ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist 解决 ...
- 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 苦咖啡 他的博客中一篇文章完美的解 ...
- zabbix登陆问题:cannot allocate shared memory for collector
问题说明:在一台zabbix被监控服务器上(64位centos6.8系统,64G内容)启动zabbix_agent,发现进程无法启动,10050端口没有起来! 启动zabbix_agent进程没有报错 ...
- ORA-27101:shared memory realm does not exist的问题
ORA-27101:shared memory realm does not exist的问题 登陆SQLPlus时出现: ORA-01034:ORACLE not avaiable ORA-2710 ...
- IPC:shared memory
#include <stdio.h> #include <sys/shm.h> #include <sys/stat.h> int main () { int se ...
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6666491 在前面一篇文章Android系统匿 ...
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共 ...
随机推荐
- 解决在vue_cli上使用mui或引入mui.js各种报错及问题
原文:https://blog.csdn.net/u012815877/article/details/81187826 在main.js里添加 import mui from './assets/j ...
- C++ Map相同key是否覆盖问题分析
C++的标准库关联容器map是不允许有key相同的键值对存在的.那么当key已经存在的情况下,我们再次插入相同的key,那么key的value会被覆盖吗? 测试代码: 测试结果: 从测试结果我们可以得 ...
- Spring源码解读--(一)源码下载
走在Java程序员这条路上,网上Java各种工具满天飞,写个简单的CRUD,相信是个开发都能写出来,于是在思考如何可以在同行业中更有竞争力(其实就是如何赚更多钱).那么,老大给我推荐了Spring源码 ...
- win10半夜自动开机的问题分析
win10半夜自动开机的系统日志: 解决方法一: 1.根据日志判断自动唤醒后,windows更新了时间和代理 服务管理器中,关闭windows update, 但是半夜还会自动开 再关闭服务管理器的w ...
- JS-闭包(Closures)和let声明块级作用域变量
闭包: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures 闭包是函数和声明该函数的词法环境的组合. let: https ...
- Js定义一个表单并提交
Js定义一个表单 var form = $("<form>"); //定义一个form表单 form.attr('style', 'display:none'); // ...
- Delphi保存网页中的图片
WEBBrowser已经打开了URL V = WEBBrowser.Document.body.createControlRange(); V1 = WEBBrow ...
- MySQL-极恶安装
1.官网下载地址:https://dev.mysql.com/downloads/mysql/ 2.安装包下载后解压,并创建my.ini配置文件 内容如下,注意两个第三个#:MySQL的安装目录,第四 ...
- Map2
map增加和更新: map["key"] = value //如果key还没有,就是增加,如果key存在就是修改 案例演示: func main() { cities := mak ...
- Struts2之下载
下载页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnco ...