@Pigmon
2019-01-02T16:59:05.000000Z
字数 14131
阅读 3590
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 -lrt
clean:
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 memory
managed_shared_memory managed_shm(open_or_create, "My_SHM_Array", 1024);
// 将 vec 存储至 shared memory, 或者使用 find_or_construct
IntVec *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 segment
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);
//Initialize shared memory STL-compatible allocator
const 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 segment
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");
// Test read
MyVector *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 allocator
const 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 更新 vector
int 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 allocator
const 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 allocator
const 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;
};