I need to allocate a user defined struct in shared memory using boost's managed_shared_memory but I am not sure how to go about this correctly. It appears that the key to getting this to work correctly is the use of custom allocators. I have successfully been able to make this work with a simple POD uint64_t type, however things become more involved when I try to put more complex types in shared memory. An example of a simple struct I would like to place in shared memory would be something along the following lines:
struct SharedMemStruct {
explicit SharedMemStruct() = default;
explicit SharedMemStruct(
const bool bField0,
const std::string& rField1,
const uint32_t& rField2)
: mField0(bField0)
, mField1(rField1)
, mField2(rField2)
{}
bool mField0;
std::string mField1;
uint32_t mField2;
};
With the POD type I successfully initialized the shared memory as follows (placing the 64 bit shared value in a named area called "FaultReport" that can be shared with another process.
// Remove shared memory on construction and destruction
struct shm_remove {
shm_remove() { shared_memory_object::remove("albfd_shared_mem"); }
~shm_remove() { shared_memory_object::remove("albfd_shared_mem"); }
} remover;
// create a new shared memory segment 2K size
managed_shared_memory managed_shm(create_only, "albfd_shared_mem", 2048);
// construct a FaultReport - default to no faults
auto pFaultWrapper = managed_shm.construct<UtlSharedIPCWrapper<uint64_t>>("FaultReport")(0);
In another process that requires access to the above FaultReport, it is a simple matter as follows:
// create a new shared memory segment 2K size
managed_shared_memory managed_shm(open_only, "albfd_shared_mem");
// shared memory must exist in
shared_memory_object shm(open_only, "albfd_shared_mem", read_write);
// lookup the FaultReport shared memory wrapper
auto pFaultReport = managed_shm.find<UtlSharedIPCWrapper<uint64_t>>("FaultReport").first;
// initialize the bit-set from the current shared memory fault report
std::bitset<64> bitSet(pFaultReport->getSharedData());
The UtlSharedIPCWrapper provides me safe access to its data type T
template<typename T>
struct UtlSharedIPCWrapper {
private:
using upgradable_mutex_type = boost::interprocess::interprocess_upgradable_mutex;
mutable upgradable_mutex_type mMutex;
/*volatile*/ T mSharedData;
public:
// explicit struct constructor used to initialize directly from existing memory
explicit UtlSharedIPCWrapper(const T& rInitialValue)
: mSharedData(rInitialValue)
{}
T getSharedData() const {
boost::interprocess::sharable_lock<upgradable_mutex_type> lock(mMutex);
return mSharedData;
}
void setSharedData(const T& rSharedData) {
boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mMutex);
// update the shared data copy mapped - scoped locked used if exception thrown
// a bit like the lock guard we normally use
this->mSharedData = rSharedData;
}
};
Aucun commentaire:
Enregistrer un commentaire