首页 技术 正文
技术 2022年11月6日
0 收藏 419 点赞 931 浏览 10186 个字

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.

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,000
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,512
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,358
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,141
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,771
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,849