In boost::interprocess
documentazione si dice come requisito per contenitori da memorizzare nella memoria condivisa:std :: vector soddisfa i requisiti del contenitore per gli allocatori Boost.Interprocess?
- contenitori STL possono non presumere che la memoria allocata con un allocatore può essere deallocato con altri allocators dello stesso tipo. Tutti gli oggetti allocatori devono essere uguali solo se la memoria allocata con un oggetto può essere deallocata con l'altro e questo può essere verificato solo con
operator==()
in fase di esecuzione. - I puntatori interni dei contenitori devono essere del tipo
allocator::pointer
ei contenitori non possono assumere cheallocator::pointer
sia un puntatore non elaborato. - Tutti gli oggetti devono essere distrutti mediante le funzioni
allocator::construct
eallocator::destroy
.
Sto utilizzando gcc 4.7.1 con -std = C++ 11 (e aumenta 1.53). È sicuro utilizzare il tipo ShmVector
sotto definito?
typedef boost::interprocess::allocator<int,
boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef std::vector<int, ShmemAllocator> ShmVector;
Ho provato un processo fittizio che utilizza questo tipo, e sembra si sta lavorando, ma non sono ancora sicuro che il vettore in gcc4.7.1 non soddisfa tutti i requisiti. Non sono particolarmente sicuro del primo requisito.
#include <iostream>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <vector>
#include <cstdlib> //std::system
typedef boost::interprocess::allocator<int,
boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef std::vector<int, ShmemAllocator> ShmVector;
int main(int argc, char *argv[])
{
if(argc == 1){ //Parent process
struct shm_remove
{
shm_remove() { boost::interprocess::shared_memory_object::remove("MySharedMemory"); }
~shm_remove(){ boost::interprocess::shared_memory_object::remove("MySharedMemory"); }
} remover;
//Create a new segment with given name and size
boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only,
"MySharedMemory", 65536);
//Initialize shared memory STL-compatible allocator
const ShmemAllocator allocator(segment.get_segment_manager());
ShmVector* v = segment.construct<ShmVector>("ShmVector")(allocator);
v->push_back(1); v->push_back(2); v->push_back(3);
//Launch child process
std::string s(argv[0]); s += " child ";
if(0 != std::system(s.c_str()))
return 1;
} else { // Child process
//Open the managed segment
boost::interprocess::managed_shared_memory segment(
boost::interprocess::open_only, "MySharedMemory");
//Find the vector using the c-string name
ShmVector *v = segment.find<ShmVector>("ShmVector").first;
for (const auto& i : *v) {
std::cout << i << " ";
}
std::cout << std::endl;
}
}
Secondo lo standard, dovrebbe andare bene. – Xeo
@Xeo Non ne sono così sicuro. Lo standard dice che le implementazioni STL sono libere di assumere un allocatore dello stesso tipo in grado di deallocare la memoria; la maggior parte delle implementazioni non si basano su questo, ma dovresti controllare la documentazione della libreria 'std'. Tuttavia, data la prevalenza di 'g ++' e 'libstdC++', sarei sorpreso se Boost non ti avvisasse esplicitamente di incompatibilità. –
@Xeo Ho trovato nello standard che il punto 3 deve essere vero per tutti gli std :: container: 23.2.1.3. Ma non è stato possibile trovare nulla per il proiettile 1 e 2. –