@Pigmon
2019-01-02T08:59:05.000000Z
字数 14131
阅读 4095
C++
https://theboostcpplibraries.com/boost.interprocess
https://www.boost.org/doc/libs/1_67_0/doc/html/interprocess.html
all:g++ test.cpp -pthread -o test -lrtclean:rm -r test
-lrt 必须在最后,否则link错误。原因不详。
TODO
#include <boost/interprocess/managed_shared_memory.hpp>#include <iostream>using namespace boost::interprocess;int main(){// 先删除bool ret = shared_memory_object::remove("My_SHM");std::cout << std::boolalpha << ret << std::endl;// 构造 managed shared memory 对象managed_shared_memory managed_shm(open_or_create, "My_SHM", 1024);int *i = managed_shm.construct<int>("My_Age")(109);std::cout << *i << '\n';// 按名字读取std::pair<int *, std::size_t> p = managed_shm.find<int>("My_Age");if (p.first)std::cout << *p.first << ":" << p.second << std::endl;}
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <iostream>using namespace boost::interprocess;typedef boost::interprocess::vector<int> IntVec;int main(){int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};IntVec vec(arr, arr + sizeof(arr) / sizeof(int));// 先删除shared_memory_object::remove("My_SHM_Array");// 构建 managed shared memorymanaged_shared_memory managed_shm(open_or_create, "My_SHM_Array", 1024);// 将 vec 存储至 shared memory, 或者使用 find_or_constructIntVec *vec_shm = managed_shm.construct<IntVec>("Numbers")(vec);std::cout << (*vec_shm)[2] << '\n';// 读取std::pair<IntVec*, std::size_t> p = managed_shm.find<IntVec>("Numbers");if (p.first){std::cout << (*(p.first))[8] << '\n';std::cout << p.second << '\n';}}
#include <boost/interprocess/managed_shared_memory.hpp>#include <iostream>using namespace boost::interprocess;int main(){try{shared_memory_object::remove("My_SHM_Array");managed_shared_memory managed_shm(open_or_create, "My_SHM_Array", 1024);int *i = managed_shm.construct<int>("Numbers")[4096](99);}catch (boost::interprocess::bad_alloc &ex){std::cerr << ex.what() << '\n';}}
#include <boost/interprocess/managed_shared_memory.hpp>#include <iostream>using namespace boost::interprocess;int main(){shared_memory_object::remove("My_SHM_Array");managed_shared_memory managed_shm(open_or_create, "My_SHM_Array", 1024);int *i = managed_shm.find_or_construct<int>("Numbers")(99);std::cout << *i << '\n';managed_shm.destroy<int>("Numbers");std::pair<int *, std::size_t> p = managed_shm.find<int>("Numbers");std::cout << p.first << '\n';}
#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("My_SHM_String");managed_shared_memory managed_shm(open_or_create, "My_SHM_String", 1024);typedef allocator<char, managed_shared_memory::segment_manager> CharAllocator;typedef basic_string<char, std::char_traits<char>, CharAllocator> AString;AString *s = managed_shm.find_or_construct<AString>("MyString")("Hello!", managed_shm.get_segment_manager());s->insert(5, ", world");std::cout << *s << '\n';}
需要在操作过程中起到类似加锁的功能,即在操作过程中不受其他进程干扰时使用。
其他进程必须也使用 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>("A_Int_Number")(99);managed_shm.construct<float>("A_Float_Number")(3.14);}int main(){shared_memory_object::remove("My_SHM_Obj");managed_shared_memory managed_shm(open_or_create, "My_SHM_Obj", 1024);// 绑定 原子操作 和 managed_shared_memory对象auto atomic_construct = std::bind(construct_objects, std::ref(managed_shm));managed_shm.atomic_func(atomic_construct);std::cout << *managed_shm.find<int>("A_Int_Number").first << '\n';std::cout << *managed_shm.find<float>("A_Float_Number").first << '\n';}
Server:
#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#include <iostream>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 segmenttypedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<int, ShmemAllocator> MyVector;int main(int argc, char *argv[]){shared_memory_object::remove("MySharedMemory");managed_shared_memory segment(create_only, "MySharedMemory", 65536);//Initialize shared memory STL-compatible allocatorconst ShmemAllocator alloc_inst(segment.get_segment_manager());MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);for (int i = 0; i < 100; ++i)myvector->push_back(i);return 0;};
Client:
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <string>#include <iostream>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 segmenttypedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<int, ShmemAllocator> MyVector;int main(int argc, char *argv[]){managed_shared_memory segment(open_only, "MySharedMemory");// Test readMyVector *vec_test = segment.find<MyVector>("MyVector").first;for (auto it = vec_test->begin(); it != vec_test->end(); it++)std::cout << (*it) << ",";std::cout << std::endl;return 0;};
使用 boost::interprocess::interprocess_mutex,可以保证被 mutex guard 的量可以由所有进程访问,因为其是存储在共享内存中的 (与boost::interprocess::named_mutex不同,后者由操作系统管理,并不是共享内存机制,无法跨进程访问)。
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <iostream>using namespace boost::interprocess;int main(){// bool ret = shared_memory_object::remove("shm");// std::cout << std::boolalpha << ret << std::endl;managed_shared_memory managed_shm(open_or_create, "shm", 1024);int *i = managed_shm.find_or_construct<int>("TheNumber")(80);interprocess_mutex *mtx = managed_shm.find_or_construct<interprocess_mutex>("mtx")();mtx->lock();++(*i);std::cout << *i << '\n';mtx->unlock();}
Server:
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <boost/interprocess/sync/interprocess_condition.hpp>#include <boost/interprocess/sync/scoped_lock.hpp>#include <string>//#include <cstdlib> //std::system#include <iostream>using namespace boost::interprocess;typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<int, ShmemAllocator> MyVector;int main(int argc, char *argv[]){shared_memory_object::remove("MySharedMemory");managed_shared_memory segment(create_only, "MySharedMemory", 65536);interprocess_mutex *mtx = segment.find_or_construct<interprocess_mutex>("mtx")();interprocess_condition *cnd = segment.find_or_construct<interprocess_condition>("cnd")();scoped_lock<interprocess_mutex> lock{*mtx};//Initialize shared memory STL-compatible allocatorconst ShmemAllocator alloc_inst(segment.get_segment_manager());MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);// 每次获取锁后,更新vector内容。// 然后放开,等 Client 得到后再更新int counter = 0;while (counter < 10){counter++;myvector->clear();for (int i = 0; i < 10; ++i)myvector->push_back(i * counter);cnd->notify_all();cnd->wait(lock);}cnd->notify_all();shared_memory_object::remove("MySharedMemory");return 0;};
Client:
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <boost/interprocess/sync/interprocess_condition.hpp>#include <boost/interprocess/sync/scoped_lock.hpp>#include <string>#include <iostream>using namespace boost::interprocess;typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<int, ShmemAllocator> MyVector;int main(int argc, char *argv[]){managed_shared_memory segment(open_only, "MySharedMemory");interprocess_mutex *mtx = segment.find_or_construct<interprocess_mutex>("mtx")();interprocess_condition *cnd = segment.find_or_construct<interprocess_condition>("cnd")();scoped_lock<interprocess_mutex> lock{*mtx};MyVector *vec_test = segment.find<MyVector>("MyVector").first;// 得到数据后放开等待 Server 更新 vectorint counter = 0;while (counter < 10){counter++;for (auto it = vec_test->begin(); it != vec_test->end(); it++)std::cout << (*it) << ",";std::cout << std::endl;cnd->notify_all();cnd->wait(lock);}cnd->notify_all();return 0;};
只是 Allocator 和上面不一样,应对类似 ESR 毫米波雷达 CAN 数据的情形。
Server:
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <boost/interprocess/sync/interprocess_condition.hpp>#include <boost/interprocess/sync/scoped_lock.hpp>#include <string>//#include <cstdlib> //std::system#include <iostream>using namespace boost::interprocess;struct some_data{int id;double info;};typedef allocator<some_data, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<some_data, ShmemAllocator> MyVector;int main(int argc, char *argv[]){shared_memory_object::remove("MySharedMemory");managed_shared_memory segment(create_only, "MySharedMemory", 65536);interprocess_mutex *mtx = segment.find_or_construct<interprocess_mutex>("mtx")();interprocess_condition *cnd = segment.find_or_construct<interprocess_condition>("cnd")();scoped_lock<interprocess_mutex> lock{*mtx};//Initialize shared memory STL-compatible allocatorconst ShmemAllocator alloc_inst(segment.get_segment_manager());MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);int counter = 0;while (counter < 10){counter++;myvector->clear();for (int i = 0; i < 10; ++i){some_data data{i * counter, 0.2 * counter};myvector->push_back(data);}cnd->notify_all();cnd->wait(lock);}cnd->notify_all();shared_memory_object::remove("MySharedMemory");return 0;};
Client:
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <boost/interprocess/sync/interprocess_condition.hpp>#include <boost/interprocess/sync/scoped_lock.hpp>#include <string>#include <iostream>using namespace boost::interprocess;struct some_data{int id;double info;};typedef allocator<some_data, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<some_data, ShmemAllocator> MyVector;int main(int argc, char *argv[]){managed_shared_memory segment(open_only, "MySharedMemory");interprocess_mutex *mtx = segment.find_or_construct<interprocess_mutex>("mtx")();interprocess_condition *cnd = segment.find_or_construct<interprocess_condition>("cnd")();scoped_lock<interprocess_mutex> lock{*mtx};MyVector *vec_test = segment.find<MyVector>("MyVector").first;int counter = 0;while (counter < 10){counter++;for (auto it = vec_test->begin(); it != vec_test->end(); it++)std::cout << "<" << (*it).id << "," << (*it).info << ">";std::cout << std::endl;cnd->notify_all();cnd->wait(lock);}cnd->notify_all();return 0;};
类似激光雷达点云数据的情形
Server:
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <boost/interprocess/sync/interprocess_condition.hpp>#include <boost/interprocess/sync/scoped_lock.hpp>#include <string>//#include <cstdlib> //std::system#include <iostream>using namespace boost::interprocess;// 即便一个简单的Vector,也必须这样用 allocator 初始化,否则 Client 找不到?typedef allocator<double, managed_shared_memory::segment_manager> DoubleAllocator;typedef vector<double, DoubleAllocator> dVec;struct some_data{int id;dVec info;};typedef allocator<some_data, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<some_data, ShmemAllocator> MyVector;int main(int argc, char *argv[]){shared_memory_object::remove("MySharedMemory");managed_shared_memory segment(create_only, "MySharedMemory", 65536);interprocess_mutex *mtx = segment.find_or_construct<interprocess_mutex>("mtx")();interprocess_condition *cnd = segment.find_or_construct<interprocess_condition>("cnd")();scoped_lock<interprocess_mutex> lock{*mtx};//Initialize shared memory STL-compatible allocatorconst ShmemAllocator alloc_inst(segment.get_segment_manager());MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);int counter = 0;while (counter < 10){counter++;myvector->clear();for (int i = 0; i < 10; ++i){std::stringstream s;s << "info_" << counter << "_" << i;const DoubleAllocator alloc_inst(segment.get_segment_manager());dVec *vec = segment.construct<dVec>(s.str().c_str())(alloc_inst);;vec->push_back(0.2 * counter);vec->push_back(2.0 * counter);some_data data{i * counter, *vec};myvector->push_back(data);}cnd->notify_all();cnd->wait(lock);}cnd->notify_all();shared_memory_object::remove("MySharedMemory");return 0;};
Client:
#include <boost/interprocess/managed_shared_memory.hpp>#include <boost/interprocess/containers/vector.hpp>#include <boost/interprocess/allocators/allocator.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <boost/interprocess/sync/interprocess_condition.hpp>#include <boost/interprocess/sync/scoped_lock.hpp>#include <string>#include <iostream>using namespace boost::interprocess;typedef allocator<double, managed_shared_memory::segment_manager> DoubleAllocator;typedef vector<double, DoubleAllocator> dVec;struct some_data{int id;dVec info;};typedef allocator<some_data, managed_shared_memory::segment_manager> ShmemAllocator;typedef vector<some_data, ShmemAllocator> MyVector;int main(int argc, char *argv[]){managed_shared_memory segment(open_only, "MySharedMemory");interprocess_mutex *mtx = segment.find_or_construct<interprocess_mutex>("mtx")();interprocess_condition *cnd = segment.find_or_construct<interprocess_condition>("cnd")();scoped_lock<interprocess_mutex> lock{*mtx};MyVector *vec_test = segment.find<MyVector>("MyVector").first;int counter = 0;while (counter < 10){counter++;for (auto it = vec_test->begin(); it != vec_test->end(); it++)std::cout << "<" << (*it).id << ":" << (*it).info[0] << "," << (*it).info[1] << ">";std::cout << std::endl;cnd->notify_all();cnd->wait(lock);}cnd->notify_all();return 0;};